Merge "Network DataSources: implement disconnect in close"
diff --git a/include/media/MediaExtractorPluginApi.h b/include/media/MediaExtractorPluginApi.h
index cccfc91..9caea3e 100644
--- a/include/media/MediaExtractorPluginApi.h
+++ b/include/media/MediaExtractorPluginApi.h
@@ -19,6 +19,8 @@
 
 #include <utils/Errors.h> // for status_t
 
+struct AMediaFormat;
+
 namespace android {
 
 struct MediaTrack;
@@ -56,7 +58,19 @@
     bool     (*supportsNonBlockingRead)(void *data);
 };
 
-struct CMediaExtractor {
+struct CMediaTrackV2 {
+    void *data;
+    void (*free)(void *data);
+
+    status_t (*start)(void *data, AMediaFormat *params);
+    status_t (*stop)(void *data);
+    status_t (*getFormat)(void *data, AMediaFormat *format);
+    status_t (*read)(void *data, MediaBufferBase **buffer, uint32_t options, int64_t seekPosUs);
+    bool     (*supportsNonBlockingRead)(void *data);
+};
+
+
+struct CMediaExtractorV1 {
     void *data;
 
     void (*free)(void *data);
@@ -73,22 +87,49 @@
     const char * (*name)(void *data);
 };
 
-typedef CMediaExtractor* (*CreatorFunc)(CDataSource *source, void *meta);
+struct CMediaExtractorV2 {
+    void *data;
+
+    void (*free)(void *data);
+    size_t (*countTracks)(void *data);
+    CMediaTrackV2* (*getTrack)(void *data, size_t index);
+    status_t (*getTrackMetaData)(
+            void *data,
+            AMediaFormat *meta,
+            size_t index, uint32_t flags);
+
+    status_t (*getMetaData)(void *data, AMediaFormat *meta);
+    uint32_t (*flags)(void *data);
+    status_t (*setMediaCas)(void *data, const uint8_t* casToken, size_t size);
+    const char * (*name)(void *data);
+};
+
+typedef CMediaExtractorV1* (*CreatorFuncV1)(CDataSource *source, void *meta);
 typedef void (*FreeMetaFunc)(void *meta);
 
 // The sniffer can optionally fill in an opaque object, "meta", that helps
 // the corresponding extractor initialize its state without duplicating
 // effort already exerted by the sniffer. If "freeMeta" is given, it will be
 // called against the opaque object when it is no longer used.
-typedef CreatorFunc (*SnifferFunc)(
+typedef CreatorFuncV1 (*SnifferFuncV1)(
         CDataSource *source, float *confidence,
         void **meta, FreeMetaFunc *freeMeta);
 
+typedef CMediaExtractorV2* (*CreatorFuncV2)(CDataSource *source, void *meta);
+
+typedef CreatorFuncV2 (*SnifferFuncV2)(
+        CDataSource *source, float *confidence,
+        void **meta, FreeMetaFunc *freeMeta);
+
+typedef CMediaExtractorV1 CMediaExtractor;
+typedef CreatorFuncV1 CreatorFunc;
+
+
 typedef struct {
     const uint8_t b[16];
 } media_uuid_t;
 
-typedef struct {
+struct ExtractorDef {
     // version number of this structure
     const uint32_t def_version;
 
@@ -104,11 +145,16 @@
     // a human readable name
     const char *extractor_name;
 
-    // the sniffer function
-    const SnifferFunc sniff;
-} ExtractorDef;
+    union {
+        SnifferFuncV1 v1;
+        SnifferFuncV2 v2;
+    } sniff;
+};
 
-const uint32_t EXTRACTORDEF_VERSION = 1;
+const uint32_t EXTRACTORDEF_VERSION_LEGACY = 1;
+const uint32_t EXTRACTORDEF_VERSION_CURRENT = 2;
+
+const uint32_t EXTRACTORDEF_VERSION = EXTRACTORDEF_VERSION_LEGACY;
 
 // each plugin library exports one function of this type
 typedef ExtractorDef (*GetExtractorDef)();
diff --git a/include/media/MediaExtractorPluginHelper.h b/include/media/MediaExtractorPluginHelper.h
index 961033b..2acc2bf 100644
--- a/include/media/MediaExtractorPluginHelper.h
+++ b/include/media/MediaExtractorPluginHelper.h
@@ -102,6 +102,77 @@
     return wrapper;
 }
 
+
+class MediaTrackHelperV2 {
+public:
+    virtual ~MediaTrackHelperV2() {};
+    virtual status_t start(AMediaFormat *params = NULL) = 0;
+    virtual status_t stop() = 0;
+    virtual status_t getFormat(AMediaFormat *format) = 0;
+
+    class ReadOptions {
+    public:
+        enum SeekMode : int32_t {
+            SEEK_PREVIOUS_SYNC,
+            SEEK_NEXT_SYNC,
+            SEEK_CLOSEST_SYNC,
+            SEEK_CLOSEST,
+            SEEK_FRAME_INDEX,
+        };
+
+        ReadOptions(uint32_t options, int64_t seekPosUs) {
+            mOptions = options;
+            mSeekPosUs = seekPosUs;
+        }
+        bool getSeekTo(int64_t *time_us, SeekMode *mode) const {
+            if ((mOptions & CMediaTrackReadOptions::SEEK) == 0) {
+                return false;
+            }
+            *time_us = mSeekPosUs;
+            *mode = (SeekMode) (mOptions & 7);
+            return true;
+        }
+        bool getNonBlocking() const {
+            return mOptions & CMediaTrackReadOptions::NONBLOCKING;
+        }
+    private:
+        uint32_t mOptions;
+        int64_t mSeekPosUs;
+    };
+
+    virtual status_t read(
+            MediaBufferBase **buffer, const ReadOptions *options = NULL) = 0;
+    virtual bool supportsNonBlockingRead() { return false; }
+};
+
+inline CMediaTrackV2 *wrapV2(MediaTrackHelperV2 *track) {
+    CMediaTrackV2 *wrapper = (CMediaTrackV2*) malloc(sizeof(CMediaTrackV2));
+    wrapper->data = track;
+    wrapper->free = [](void *data) -> void {
+        delete (MediaTrackHelperV2*)(data);
+    };
+    wrapper->start = [](void *data, AMediaFormat *params) -> status_t {
+        return ((MediaTrackHelperV2*)data)->start(params);
+    };
+    wrapper->stop = [](void *data) -> status_t {
+        return ((MediaTrackHelperV2*)data)->stop();
+    };
+    wrapper->getFormat = [](void *data, AMediaFormat *meta) -> status_t {
+        return ((MediaTrackHelperV2*)data)->getFormat(meta);
+    };
+    wrapper->read = [](void *data, MediaBufferBase **buffer,  uint32_t options, int64_t seekPosUs)
+            -> status_t {
+        MediaTrackHelperV2::ReadOptions opts(options, seekPosUs);
+        return ((MediaTrackHelperV2*)data)->read(buffer, &opts);
+    };
+    wrapper->supportsNonBlockingRead = [](void *data) -> bool {
+                return ((MediaTrackHelperV2*)data)->supportsNonBlockingRead();
+    };
+    return wrapper;
+}
+
+
+
 // extractor plugins can derive from this class which looks remarkably
 // like MediaExtractor and can be easily wrapped in the required C API
 class MediaExtractorPluginHelper
@@ -187,6 +258,89 @@
     return wrapper;
 }
 
+class MediaExtractorPluginHelperV2
+{
+public:
+    virtual ~MediaExtractorPluginHelperV2() {}
+    virtual size_t countTracks() = 0;
+    virtual MediaTrackHelperV2 *getTrack(size_t index) = 0;
+
+    enum GetTrackMetaDataFlags {
+        kIncludeExtensiveMetaData = 1
+    };
+    virtual status_t getTrackMetaData(
+            AMediaFormat *meta,
+            size_t index, uint32_t flags = 0) = 0;
+
+    // Return container specific meta-data. The default implementation
+    // returns an empty metadata object.
+    virtual status_t getMetaData(AMediaFormat *meta) = 0;
+
+    enum Flags {
+        CAN_SEEK_BACKWARD  = 1,  // the "seek 10secs back button"
+        CAN_SEEK_FORWARD   = 2,  // the "seek 10secs forward button"
+        CAN_PAUSE          = 4,
+        CAN_SEEK           = 8,  // the "seek bar"
+    };
+
+    // If subclasses do _not_ override this, the default is
+    // CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE
+    virtual uint32_t flags() const {
+        return CAN_SEEK_BACKWARD | CAN_SEEK_FORWARD | CAN_SEEK | CAN_PAUSE;
+    };
+
+    virtual status_t setMediaCas(const uint8_t* /*casToken*/, size_t /*size*/) {
+        return INVALID_OPERATION;
+    }
+
+    virtual const char * name() { return "<unspecified>"; }
+
+protected:
+    MediaExtractorPluginHelperV2() {}
+
+private:
+    MediaExtractorPluginHelperV2(const MediaExtractorPluginHelperV2 &);
+    MediaExtractorPluginHelperV2 &operator=(const MediaExtractorPluginHelperV2 &);
+};
+
+inline CMediaExtractorV2 *wrapV2(MediaExtractorPluginHelperV2 *extractor) {
+    CMediaExtractorV2 *wrapper = (CMediaExtractorV2*) malloc(sizeof(CMediaExtractorV2));
+    wrapper->data = extractor;
+    wrapper->free = [](void *data) -> void {
+        delete (MediaExtractorPluginHelperV2*)(data);
+    };
+    wrapper->countTracks = [](void *data) -> size_t {
+        return ((MediaExtractorPluginHelperV2*)data)->countTracks();
+    };
+    wrapper->getTrack = [](void *data, size_t index) -> CMediaTrackV2* {
+        return wrapV2(((MediaExtractorPluginHelperV2*)data)->getTrack(index));
+    };
+    wrapper->getTrackMetaData = [](
+            void *data,
+            AMediaFormat *meta,
+            size_t index, uint32_t flags) -> status_t {
+        return ((MediaExtractorPluginHelperV2*)data)->getTrackMetaData(meta, index, flags);
+    };
+    wrapper->getMetaData = [](
+            void *data,
+            AMediaFormat *meta) -> status_t {
+        return ((MediaExtractorPluginHelperV2*)data)->getMetaData(meta);
+    };
+    wrapper->flags = [](
+            void *data) -> uint32_t {
+        return ((MediaExtractorPluginHelperV2*)data)->flags();
+    };
+    wrapper->setMediaCas = [](
+            void *data, const uint8_t *casToken, size_t size) -> status_t {
+        return ((MediaExtractorPluginHelperV2*)data)->setMediaCas(casToken, size);
+    };
+    wrapper->name = [](
+            void *data) -> const char * {
+        return ((MediaExtractorPluginHelperV2*)data)->name();
+    };
+    return wrapper;
+}
+
 /* adds some convience methods */
 class DataSourceHelper {
 public:
diff --git a/include/media/MediaTrack.h b/include/media/MediaTrack.h
index 3f77bda..174f4cc 100644
--- a/include/media/MediaTrack.h
+++ b/include/media/MediaTrack.h
@@ -22,6 +22,7 @@
 
 #include <binder/IMemory.h>
 #include <binder/MemoryDealer.h>
+#include <media/MediaExtractorPluginApi.h>
 #include <media/stagefright/MediaErrors.h>
 #include <media/stagefright/MetaData.h>
 #include <media/MediaExtractorPluginApi.h>
@@ -76,13 +77,23 @@
             SEEK_FRAME_INDEX = CMediaTrackReadOptions::SEEK_FRAME_INDEX,
         };
 
-        ReadOptions();
+        ReadOptions() {
+            reset();
+        }
 
         // Reset everything back to defaults.
-        void reset();
+        void reset() {
+            mOptions = 0;
+            mSeekTimeUs = 0;
+            mNonBlocking = false;
+        }
 
         void setSeekTo(int64_t time_us, SeekMode mode = SEEK_CLOSEST_SYNC);
-        void clearSeekTo();
+        void clearSeekTo() {
+            mOptions &= ~kSeekTo_Option;
+            mSeekTimeUs = 0;
+            mSeekMode = SEEK_CLOSEST_SYNC;
+        }
         bool getSeekTo(int64_t *time_us, SeekMode *mode) const;
 
         void setNonBlocking();
@@ -146,6 +157,24 @@
     CMediaTrack *wrapper;
 };
 
+class MediaTrackCUnwrapperV2 : public MediaTrack {
+public:
+    explicit MediaTrackCUnwrapperV2(CMediaTrackV2 *wrapper);
+
+    virtual status_t start(MetaDataBase *params = NULL);
+    virtual status_t stop();
+    virtual status_t getFormat(MetaDataBase& format);
+    virtual status_t read(MediaBufferBase **buffer, const ReadOptions *options = NULL);
+
+    virtual bool supportNonblockingRead();
+
+protected:
+    virtual ~MediaTrackCUnwrapperV2();
+
+private:
+    CMediaTrackV2 *wrapper;
+};
+
 }  // namespace android
 
 #endif  // MEDIA_SOURCE_BASE_H_
diff --git a/media/extractors/aac/AACExtractor.cpp b/media/extractors/aac/AACExtractor.cpp
index 9effd57..b52aec5 100644
--- a/media/extractors/aac/AACExtractor.cpp
+++ b/media/extractors/aac/AACExtractor.cpp
@@ -393,7 +393,7 @@
         UUID("4fd80eae-03d2-4d72-9eb9-48fa6bb54613"),
         1, // version
         "AAC Extractor",
-        Sniff
+        { Sniff }
     };
 }
 
diff --git a/media/extractors/amr/AMRExtractor.cpp b/media/extractors/amr/AMRExtractor.cpp
index 6648103..8039f3a 100644
--- a/media/extractors/amr/AMRExtractor.cpp
+++ b/media/extractors/amr/AMRExtractor.cpp
@@ -370,19 +370,21 @@
         UUID("c86639c9-2f31-40ac-a715-fa01b4493aaf"),
         1,
         "AMR Extractor",
-        [](
-                CDataSource *source,
-                float *confidence,
-                void **,
-                FreeMetaFunc *) -> CreatorFunc {
-            DataSourceHelper helper(source);
-            if (SniffAMR(&helper, nullptr, confidence)) {
-                return [](
-                        CDataSource *source,
-                        void *) -> CMediaExtractor* {
-                    return wrap(new AMRExtractor(new DataSourceHelper(source)));};
+        {
+           [](
+                    CDataSource *source,
+                    float *confidence,
+                    void **,
+                    FreeMetaFunc *) -> CreatorFunc {
+                DataSourceHelper helper(source);
+                if (SniffAMR(&helper, nullptr, confidence)) {
+                    return [](
+                            CDataSource *source,
+                            void *) -> CMediaExtractor* {
+                        return wrap(new AMRExtractor(new DataSourceHelper(source)));};
+                }
+                return NULL;
             }
-            return NULL;
         }
     };
 }
diff --git a/media/extractors/flac/FLACExtractor.cpp b/media/extractors/flac/FLACExtractor.cpp
index c10a557..debdcfc 100644
--- a/media/extractors/flac/FLACExtractor.cpp
+++ b/media/extractors/flac/FLACExtractor.cpp
@@ -866,19 +866,21 @@
             UUID("1364b048-cc45-4fda-9934-327d0ebf9829"),
             1,
             "FLAC Extractor",
-            [](
-                    CDataSource *source,
-                    float *confidence,
-                    void **,
-                    FreeMetaFunc *) -> CreatorFunc {
-                DataSourceHelper helper(source);
-                if (SniffFLAC(&helper, confidence)) {
-                    return [](
-                            CDataSource *source,
-                            void *) -> CMediaExtractor* {
-                        return wrap(new FLACExtractor(new DataSourceHelper(source)));};
+            {
+                [](
+                        CDataSource *source,
+                        float *confidence,
+                        void **,
+                        FreeMetaFunc *) -> CreatorFunc {
+                    DataSourceHelper helper(source);
+                    if (SniffFLAC(&helper, confidence)) {
+                        return [](
+                                CDataSource *source,
+                                void *) -> CMediaExtractor* {
+                            return wrap(new FLACExtractor(new DataSourceHelper(source)));};
+                    }
+                    return NULL;
                 }
-                return NULL;
             }
      };
 }
diff --git a/media/extractors/midi/Android.bp b/media/extractors/midi/Android.bp
index fde09df18..c5df5c7 100644
--- a/media/extractors/midi/Android.bp
+++ b/media/extractors/midi/Android.bp
@@ -9,6 +9,7 @@
     shared_libs: [
         "liblog",
         "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
diff --git a/media/extractors/midi/MidiExtractor.cpp b/media/extractors/midi/MidiExtractor.cpp
index 5b61f34..9b0f4e7 100644
--- a/media/extractors/midi/MidiExtractor.cpp
+++ b/media/extractors/midi/MidiExtractor.cpp
@@ -33,16 +33,16 @@
 // how many Sonivox output buffers to aggregate into one MediaBufferBase
 static const int NUM_COMBINE_BUFFERS = 4;
 
-class MidiSource : public MediaTrackHelper {
+class MidiSource : public MediaTrackHelperV2 {
 
 public:
     MidiSource(
             MidiEngine &engine,
-            MetaDataBase &trackMetadata);
+            AMediaFormat *trackMetadata);
 
-    virtual status_t start(MetaDataBase *params);
+    virtual status_t start(AMediaFormat *params);
     virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase&);
+    virtual status_t getFormat(AMediaFormat *);
 
     virtual status_t read(
             MediaBufferBase **buffer, const ReadOptions *options = NULL);
@@ -52,7 +52,7 @@
 
 private:
     MidiEngine &mEngine;
-    MetaDataBase &mTrackMetadata;
+    AMediaFormat *mTrackMetadata;
     bool mInitCheck;
     bool mStarted;
 
@@ -69,7 +69,7 @@
 
 MidiSource::MidiSource(
         MidiEngine &engine,
-        MetaDataBase &trackMetadata)
+        AMediaFormat *trackMetadata)
     : mEngine(engine),
       mTrackMetadata(trackMetadata),
       mInitCheck(false),
@@ -87,7 +87,7 @@
     }
 }
 
-status_t MidiSource::start(MetaDataBase * /* params */)
+status_t MidiSource::start(AMediaFormat * /* params */)
 {
     ALOGV("MidiSource::start");
 
@@ -108,9 +108,9 @@
     return OK;
 }
 
-status_t MidiSource::getFormat(MetaDataBase &meta)
+status_t MidiSource::getFormat(AMediaFormat *meta)
 {
-    meta = mTrackMetadata;
+    AMediaFormat_copy(meta, mTrackMetadata);
     return OK;
 }
 
@@ -143,8 +143,8 @@
 // MidiEngine
 
 MidiEngine::MidiEngine(CDataSource *dataSource,
-        MetaDataBase *fileMetadata,
-        MetaDataBase *trackMetadata) :
+        AMediaFormat *fileMetadata,
+        AMediaFormat *trackMetadata) :
             mGroup(NULL),
             mEasData(NULL),
             mEasHandle(NULL),
@@ -170,16 +170,20 @@
     }
 
     if (fileMetadata != NULL) {
-        fileMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MIDI);
+        AMediaFormat_setString(fileMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MIDI);
     }
 
     if (trackMetadata != NULL) {
-        trackMetadata->setCString(kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
-        trackMetadata->setInt64(kKeyDuration, 1000ll * temp); // milli->micro
+        AMediaFormat_setString(trackMetadata, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
+        AMediaFormat_setInt64(
+                trackMetadata, AMEDIAFORMAT_KEY_DURATION, 1000ll * temp); // milli->micro
         mEasConfig = EAS_Config();
-        trackMetadata->setInt32(kKeySampleRate, mEasConfig->sampleRate);
-        trackMetadata->setInt32(kKeyChannelCount, mEasConfig->numChannels);
-        trackMetadata->setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_SAMPLE_RATE, mEasConfig->sampleRate);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mEasConfig->numChannels);
+        AMediaFormat_setInt32(
+                trackMetadata, AMEDIAFORMAT_KEY_PCM_ENCODING, kAudioEncodingPcm16bit);
     }
     mIsInitialized = true;
 }
@@ -268,13 +272,17 @@
       mInitCheck(false)
 {
     ALOGV("MidiExtractor ctor");
-    mEngine = new MidiEngine(mDataSource, &mFileMetadata, &mTrackMetadata);
+    mFileMetadata = AMediaFormat_new();
+    mTrackMetadata = AMediaFormat_new();
+    mEngine = new MidiEngine(mDataSource, mFileMetadata, mTrackMetadata);
     mInitCheck = mEngine->initCheck();
 }
 
 MidiExtractor::~MidiExtractor()
 {
     ALOGV("MidiExtractor dtor");
+    AMediaFormat_delete(mFileMetadata);
+    AMediaFormat_delete(mTrackMetadata);
 }
 
 size_t MidiExtractor::countTracks()
@@ -282,7 +290,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrackHelper *MidiExtractor::getTrack(size_t index)
+MediaTrackHelperV2 *MidiExtractor::getTrack(size_t index)
 {
     if (mInitCheck != OK || index > 0) {
         return NULL;
@@ -291,20 +299,20 @@
 }
 
 status_t MidiExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     ALOGV("MidiExtractor::getTrackMetaData");
     if (mInitCheck != OK || index > 0) {
         return UNKNOWN_ERROR;
     }
-    meta = mTrackMetadata;
+    AMediaFormat_copy(meta, mTrackMetadata);
     return OK;
 }
 
-status_t MidiExtractor::getMetaData(MetaDataBase &meta)
+status_t MidiExtractor::getMetaData(AMediaFormat *meta)
 {
     ALOGV("MidiExtractor::getMetaData");
-    meta = mFileMetadata;
+    AMediaFormat_copy(meta, mFileMetadata);
     return OK;
 }
 
@@ -323,27 +331,30 @@
 
 }
 
+
 extern "C" {
 // This is the only symbol that needs to be exported
 __attribute__ ((visibility ("default")))
 ExtractorDef GETEXTRACTORDEF() {
     return {
-        EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION_CURRENT,
         UUID("ef6cca0a-f8a2-43e6-ba5f-dfcd7c9a7ef2"),
         1,
         "MIDI Extractor",
-        [](
+        {
+            .v2 = [](
                 CDataSource *source,
                 float *confidence,
                 void **,
-                FreeMetaFunc *) -> CreatorFunc {
-            if (SniffMidi(source, confidence)) {
-                return [](
-                        CDataSource *source,
-                        void *) -> CMediaExtractor* {
-                    return wrap(new MidiExtractor(source));};
+                FreeMetaFunc *) -> CreatorFuncV2 {
+                if (SniffMidi(source, confidence)) {
+                    return [](
+                            CDataSource *source,
+                            void *) -> CMediaExtractorV2* {
+                        return wrapV2(new MidiExtractor(source));};
+                }
+                return NULL;
             }
-            return NULL;
         }
     };
 }
diff --git a/media/extractors/midi/MidiExtractor.h b/media/extractors/midi/MidiExtractor.h
index 2147297..d82c5be 100644
--- a/media/extractors/midi/MidiExtractor.h
+++ b/media/extractors/midi/MidiExtractor.h
@@ -22,8 +22,8 @@
 #include <media/MediaExtractorPluginHelper.h>
 #include <media/stagefright/MediaBufferBase.h>
 #include <media/stagefright/MediaBufferGroup.h>
-#include <media/stagefright/MetaDataBase.h>
 #include <media/MidiIoWrapper.h>
+#include <media/NdkMediaFormat.h>
 #include <utils/String8.h>
 #include <libsonivox/eas.h>
 
@@ -32,8 +32,8 @@
 class MidiEngine {
 public:
     explicit MidiEngine(CDataSource *dataSource,
-            MetaDataBase *fileMetadata,
-            MetaDataBase *trackMetadata);
+            AMediaFormat *fileMetadata,
+            AMediaFormat *trackMetadata);
     ~MidiEngine();
 
     status_t initCheck();
@@ -51,16 +51,16 @@
     bool mIsInitialized;
 };
 
-class MidiExtractor : public MediaExtractorPluginHelper {
+class MidiExtractor : public MediaExtractorPluginHelperV2 {
 
 public:
     explicit MidiExtractor(CDataSource *source);
 
     virtual size_t countTracks();
-    virtual MediaTrackHelper *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelperV2 *getTrack(size_t index);
+    virtual status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "MidiExtractor"; }
 
 protected:
@@ -69,10 +69,10 @@
 private:
     CDataSource *mDataSource;
     status_t mInitCheck;
-    MetaDataBase mFileMetadata;
+    AMediaFormat *mFileMetadata;
 
     // There is only one track
-    MetaDataBase mTrackMetadata;
+    AMediaFormat *mTrackMetadata;
 
     MidiEngine *mEngine;
 
diff --git a/media/extractors/mkv/MatroskaExtractor.cpp b/media/extractors/mkv/MatroskaExtractor.cpp
index 4ef6892..73c8d17 100644
--- a/media/extractors/mkv/MatroskaExtractor.cpp
+++ b/media/extractors/mkv/MatroskaExtractor.cpp
@@ -1645,19 +1645,21 @@
         UUID("abbedd92-38c4-4904-a4c1-b3f45f899980"),
         1,
         "Matroska Extractor",
-        [](
-                CDataSource *source,
-                float *confidence,
-                void **,
-                FreeMetaFunc *) -> CreatorFunc {
-            DataSourceHelper helper(source);
-            if (SniffMatroska(&helper, confidence)) {
-                return [](
-                        CDataSource *source,
-                        void *) -> CMediaExtractor* {
-                    return wrap(new MatroskaExtractor(new DataSourceHelper(source)));};
+        {
+            [](
+                    CDataSource *source,
+                    float *confidence,
+                    void **,
+                    FreeMetaFunc *) -> CreatorFunc {
+                DataSourceHelper helper(source);
+                if (SniffMatroska(&helper, confidence)) {
+                    return [](
+                            CDataSource *source,
+                            void *) -> CMediaExtractor* {
+                        return wrap(new MatroskaExtractor(new DataSourceHelper(source)));};
+                }
+                return NULL;
             }
-            return NULL;
         }
     };
 }
diff --git a/media/extractors/mp3/MP3Extractor.cpp b/media/extractors/mp3/MP3Extractor.cpp
index 165ce50..e56a71b 100644
--- a/media/extractors/mp3/MP3Extractor.cpp
+++ b/media/extractors/mp3/MP3Extractor.cpp
@@ -718,7 +718,7 @@
         UUID("812a3f6c-c8cf-46de-b529-3774b14103d4"),
         1, // version
         "MP3 Extractor",
-        Sniff
+        { Sniff }
     };
 }
 
diff --git a/media/extractors/mp4/MPEG4Extractor.cpp b/media/extractors/mp4/MPEG4Extractor.cpp
index da240d6..e3da6d8 100644
--- a/media/extractors/mp4/MPEG4Extractor.cpp
+++ b/media/extractors/mp4/MPEG4Extractor.cpp
@@ -5969,7 +5969,7 @@
         UUID("27575c67-4417-4c54-8d3d-8e626985a164"),
         1, // version
         "MP4 Extractor",
-        Sniff
+        { Sniff }
     };
 }
 
diff --git a/media/extractors/mpeg2/ExtractorBundle.cpp b/media/extractors/mpeg2/ExtractorBundle.cpp
index 88c2d87..366aa59 100644
--- a/media/extractors/mpeg2/ExtractorBundle.cpp
+++ b/media/extractors/mpeg2/ExtractorBundle.cpp
@@ -35,24 +35,26 @@
         UUID("3d1dcfeb-e40a-436d-a574-c2438a555e5f"),
         1,
         "MPEG2-PS/TS Extractor",
-        [](
-                CDataSource *source,
-                float *confidence,
-                void **,
-                FreeMetaFunc *) -> CreatorFunc {
-            DataSourceHelper helper(source);
-            if (SniffMPEG2TS(&helper, confidence)) {
-                return [](
-                        CDataSource *source,
-                        void *) -> CMediaExtractor* {
-                    return wrap(new MPEG2TSExtractor(new DataSourceHelper(source)));};
-            } else if (SniffMPEG2PS(&helper, confidence)) {
-                        return [](
-                                CDataSource *source,
-                                void *) -> CMediaExtractor* {
-                            return wrap(new MPEG2PSExtractor(new DataSourceHelper(source)));};
+        {
+            [](
+                    CDataSource *source,
+                    float *confidence,
+                    void **,
+                    FreeMetaFunc *) -> CreatorFunc {
+                DataSourceHelper helper(source);
+                if (SniffMPEG2TS(&helper, confidence)) {
+                    return [](
+                            CDataSource *source,
+                            void *) -> CMediaExtractor* {
+                        return wrap(new MPEG2TSExtractor(new DataSourceHelper(source)));};
+                } else if (SniffMPEG2PS(&helper, confidence)) {
+                            return [](
+                                    CDataSource *source,
+                                    void *) -> CMediaExtractor* {
+                                return wrap(new MPEG2PSExtractor(new DataSourceHelper(source)));};
+                }
+                return NULL;
             }
-            return NULL;
         }
     };
 }
diff --git a/media/extractors/ogg/OggExtractor.cpp b/media/extractors/ogg/OggExtractor.cpp
index 668b012..dc6b0b7 100644
--- a/media/extractors/ogg/OggExtractor.cpp
+++ b/media/extractors/ogg/OggExtractor.cpp
@@ -1280,7 +1280,7 @@
         UUID("8cc5cd06-f772-495e-8a62-cba9649374e9"),
         1, // version
         "Ogg Extractor",
-        Sniff
+        { Sniff }
     };
 }
 
diff --git a/media/extractors/wav/Android.bp b/media/extractors/wav/Android.bp
index 067933e..d8b4144 100644
--- a/media/extractors/wav/Android.bp
+++ b/media/extractors/wav/Android.bp
@@ -9,6 +9,7 @@
     shared_libs: [
         "liblog",
         "libmediaextractor",
+        "libmediandk",
     ],
 
     static_libs: [
diff --git a/media/extractors/wav/WAVExtractor.cpp b/media/extractors/wav/WAVExtractor.cpp
index cda568b..1b7c2e4 100644
--- a/media/extractors/wav/WAVExtractor.cpp
+++ b/media/extractors/wav/WAVExtractor.cpp
@@ -54,17 +54,17 @@
     return ptr[1] << 8 | ptr[0];
 }
 
-struct WAVSource : public MediaTrackHelper {
+struct WAVSource : public MediaTrackHelperV2 {
     WAVSource(
             DataSourceHelper *dataSource,
-            MetaDataBase &meta,
+            AMediaFormat *meta,
             uint16_t waveFormat,
             int32_t bitsPerSample,
             off64_t offset, size_t size);
 
-    virtual status_t start(MetaDataBase *params = NULL);
+    virtual status_t start(AMediaFormat *params = NULL);
     virtual status_t stop();
-    virtual status_t getFormat(MetaDataBase &meta);
+    virtual status_t getFormat(AMediaFormat *meta);
 
     virtual status_t read(
             MediaBufferBase **buffer, const ReadOptions *options = NULL);
@@ -78,7 +78,7 @@
     static const size_t kMaxFrameSize;
 
     DataSourceHelper *mDataSource;
-    MetaDataBase &mMeta;
+    AMediaFormat *mMeta;
     uint16_t mWaveFormat;
     int32_t mSampleRate;
     int32_t mNumChannels;
@@ -97,17 +97,19 @@
     : mDataSource(source),
       mValidFormat(false),
       mChannelMask(CHANNEL_MASK_USE_CHANNEL_ORDER) {
+    mTrackMeta = AMediaFormat_new();
     mInitCheck = init();
 }
 
 WAVExtractor::~WAVExtractor() {
     delete mDataSource;
+    AMediaFormat_delete(mTrackMeta);
 }
 
-status_t WAVExtractor::getMetaData(MetaDataBase &meta) {
-    meta.clear();
+status_t WAVExtractor::getMetaData(AMediaFormat *meta) {
+    AMediaFormat_clear(meta);
     if (mInitCheck == OK) {
-        meta.setCString(kKeyMIMEType, MEDIA_MIMETYPE_CONTAINER_WAV);
+        AMediaFormat_setString(meta, AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_CONTAINER_WAV);
     }
 
     return OK;
@@ -117,7 +119,7 @@
     return mInitCheck == OK ? 1 : 0;
 }
 
-MediaTrackHelper *WAVExtractor::getTrack(size_t index) {
+MediaTrackHelperV2 *WAVExtractor::getTrack(size_t index) {
     if (mInitCheck != OK || index > 0) {
         return NULL;
     }
@@ -128,13 +130,13 @@
 }
 
 status_t WAVExtractor::getTrackMetaData(
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         size_t index, uint32_t /* flags */) {
     if (mInitCheck != OK || index > 0) {
         return UNKNOWN_ERROR;
     }
 
-    meta = mTrackMeta;
+    AMediaFormat_copy(meta, mTrackMeta);
     return OK;
 }
 
@@ -284,33 +286,34 @@
                 mDataOffset = offset;
                 mDataSize = chunkSize;
 
-                mTrackMeta.clear();
+                AMediaFormat_clear(mTrackMeta);
 
                 switch (mWaveFormat) {
                     case WAVE_FORMAT_PCM:
                     case WAVE_FORMAT_IEEE_FLOAT:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_RAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_RAW);
                         break;
                     case WAVE_FORMAT_ALAW:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_G711_ALAW);
                         break;
                     case WAVE_FORMAT_MSGSM:
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_MSGSM);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_MSGSM);
                         break;
                     default:
                         CHECK_EQ(mWaveFormat, (uint16_t)WAVE_FORMAT_MULAW);
-                        mTrackMeta.setCString(
-                                kKeyMIMEType, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
+                        AMediaFormat_setString(mTrackMeta,
+                                AMEDIAFORMAT_KEY_MIME, MEDIA_MIMETYPE_AUDIO_G711_MLAW);
                         break;
                 }
 
-                mTrackMeta.setInt32(kKeyChannelCount, mNumChannels);
-                mTrackMeta.setInt32(kKeyChannelMask, mChannelMask);
-                mTrackMeta.setInt32(kKeySampleRate, mSampleRate);
-                mTrackMeta.setInt32(kKeyPcmEncoding, kAudioEncodingPcm16bit);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, mNumChannels);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_CHANNEL_MASK, mChannelMask);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, mSampleRate);
+                AMediaFormat_setInt32(mTrackMeta, AMEDIAFORMAT_KEY_PCM_ENCODING,
+                        kAudioEncodingPcm16bit);
 
                 int64_t durationUs = 0;
                 if (mWaveFormat == WAVE_FORMAT_MSGSM) {
@@ -332,7 +335,7 @@
                         1000000LL * num_samples / mSampleRate;
                 }
 
-                mTrackMeta.setInt64(kKeyDuration, durationUs);
+                AMediaFormat_setInt64(mTrackMeta, AMEDIAFORMAT_KEY_DURATION, durationUs);
 
                 return OK;
             }
@@ -348,7 +351,7 @@
 
 WAVSource::WAVSource(
         DataSourceHelper *dataSource,
-        MetaDataBase &meta,
+        AMediaFormat *meta,
         uint16_t waveFormat,
         int32_t bitsPerSample,
         off64_t offset, size_t size)
@@ -362,10 +365,10 @@
       mSize(size),
       mStarted(false),
       mGroup(NULL) {
-    CHECK(mMeta.findInt32(kKeySampleRate, &mSampleRate));
-    CHECK(mMeta.findInt32(kKeyChannelCount, &mNumChannels));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_SAMPLE_RATE, &mSampleRate));
+    CHECK(AMediaFormat_getInt32(mMeta, AMEDIAFORMAT_KEY_CHANNEL_COUNT, &mNumChannels));
 
-    mMeta.setInt32(kKeyMaxInputSize, kMaxFrameSize);
+    AMediaFormat_setInt32(mMeta, AMEDIAFORMAT_KEY_MAX_INPUT_SIZE, kMaxFrameSize);
 }
 
 WAVSource::~WAVSource() {
@@ -374,7 +377,7 @@
     }
 }
 
-status_t WAVSource::start(MetaDataBase * /* params */) {
+status_t WAVSource::start(AMediaFormat * /* params */) {
     ALOGV("WAVSource::start");
 
     CHECK(!mStarted);
@@ -407,10 +410,10 @@
     return OK;
 }
 
-status_t WAVSource::getFormat(MetaDataBase &meta) {
+status_t WAVSource::getFormat(AMediaFormat *meta) {
     ALOGV("WAVSource::getFormat");
 
-    meta = mMeta;
+    AMediaFormat_copy(meta, mMeta);
     return OK;
 }
 
@@ -544,13 +547,13 @@
 
 ////////////////////////////////////////////////////////////////////////////////
 
-static CMediaExtractor* CreateExtractor(
+static CMediaExtractorV2* CreateExtractor(
         CDataSource *source,
         void *) {
-    return wrap(new WAVExtractor(new DataSourceHelper(source)));
+    return wrapV2(new WAVExtractor(new DataSourceHelper(source)));
 }
 
-static CreatorFunc Sniff(
+static CreatorFuncV2 Sniff(
         CDataSource *source,
         float *confidence,
         void **,
@@ -584,11 +587,11 @@
 __attribute__ ((visibility ("default")))
 ExtractorDef GETEXTRACTORDEF() {
     return {
-        EXTRACTORDEF_VERSION,
+        EXTRACTORDEF_VERSION_CURRENT,
         UUID("7d613858-5837-4a38-84c5-332d1cddee27"),
         1, // version
         "WAV Extractor",
-        Sniff
+        { .v2 = Sniff }
     };
 }
 
diff --git a/media/extractors/wav/WAVExtractor.h b/media/extractors/wav/WAVExtractor.h
index a7c2691..2822e80 100644
--- a/media/extractors/wav/WAVExtractor.h
+++ b/media/extractors/wav/WAVExtractor.h
@@ -21,7 +21,7 @@
 #include <utils/Errors.h>
 #include <media/MediaExtractorPluginApi.h>
 #include <media/MediaExtractorPluginHelper.h>
-#include <media/stagefright/MetaDataBase.h>
+#include <media/NdkMediaFormat.h>
 
 namespace android {
 
@@ -29,15 +29,15 @@
 struct CDataSource;
 class String8;
 
-class WAVExtractor : public MediaExtractorPluginHelper {
+class WAVExtractor : public MediaExtractorPluginHelperV2 {
 public:
     explicit WAVExtractor(DataSourceHelper *source);
 
     virtual size_t countTracks();
-    virtual MediaTrackHelper *getTrack(size_t index);
-    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags);
+    virtual MediaTrackHelperV2 *getTrack(size_t index);
+    virtual status_t getTrackMetaData(AMediaFormat *meta, size_t index, uint32_t flags);
 
-    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual status_t getMetaData(AMediaFormat *meta);
     virtual const char * name() { return "WAVExtractor"; }
 
     virtual ~WAVExtractor();
@@ -53,7 +53,7 @@
     uint16_t mBitsPerSample;
     off64_t mDataOffset;
     size_t mDataSize;
-    MetaDataBase mTrackMeta;
+    AMediaFormat *mTrackMeta;
 
     status_t init();
 
diff --git a/media/libmedia/Android.bp b/media/libmedia/Android.bp
index 2389a5d..bb87b10 100644
--- a/media/libmedia/Android.bp
+++ b/media/libmedia/Android.bp
@@ -176,7 +176,6 @@
         "IResourceManagerClient.cpp",
         "IResourceManagerService.cpp",
         "IStreamSource.cpp",
-        "MediaTrack.cpp",
         "MediaUtils.cpp",
         "Metadata.cpp",
         "mediarecorder.cpp",
diff --git a/media/libmedia/MediaTrack.cpp b/media/libmedia/MediaTrack.cpp
deleted file mode 100644
index 7117b94..0000000
--- a/media/libmedia/MediaTrack.cpp
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * Copyright (C) 2009 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include <mutex>
-
-#include <media/MediaTrack.h>
-
-namespace android {
-
-MediaTrack::MediaTrack() {}
-
-MediaTrack::~MediaTrack() {}
-
-////////////////////////////////////////////////////////////////////////////////
-
-MediaTrack::ReadOptions::ReadOptions() {
-    reset();
-}
-
-void MediaTrack::ReadOptions::reset() {
-    mOptions = 0;
-    mSeekTimeUs = 0;
-    mNonBlocking = false;
-}
-
-void MediaTrack::ReadOptions::setNonBlocking() {
-    mNonBlocking = true;
-}
-
-void MediaTrack::ReadOptions::clearNonBlocking() {
-    mNonBlocking = false;
-}
-
-bool MediaTrack::ReadOptions::getNonBlocking() const {
-    return mNonBlocking;
-}
-
-void MediaTrack::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
-    mOptions |= kSeekTo_Option;
-    mSeekTimeUs = time_us;
-    mSeekMode = mode;
-}
-
-void MediaTrack::ReadOptions::clearSeekTo() {
-    mOptions &= ~kSeekTo_Option;
-    mSeekTimeUs = 0;
-    mSeekMode = SEEK_CLOSEST_SYNC;
-}
-
-bool MediaTrack::ReadOptions::getSeekTo(
-        int64_t *time_us, SeekMode *mode) const {
-    *time_us = mSeekTimeUs;
-    *mode = mSeekMode;
-    return (mOptions & kSeekTo_Option) != 0;
-}
-
-MediaTrackCUnwrapper::MediaTrackCUnwrapper(CMediaTrack *cmediatrack) {
-    wrapper = cmediatrack;
-}
-
-MediaTrackCUnwrapper::~MediaTrackCUnwrapper() {
-    wrapper->free(wrapper->data);
-    free(wrapper);
-}
-
-status_t MediaTrackCUnwrapper::start(MetaDataBase *params) {
-    return wrapper->start(wrapper->data, params);
-}
-
-status_t MediaTrackCUnwrapper::stop() {
-    return wrapper->stop(wrapper->data);
-}
-
-status_t MediaTrackCUnwrapper::getFormat(MetaDataBase& format) {
-    return wrapper->getFormat(wrapper->data, format);
-}
-
-status_t MediaTrackCUnwrapper::read(MediaBufferBase **buffer, const ReadOptions *options) {
-
-    uint32_t opts = 0;
-
-    if (options->getNonBlocking()) {
-        opts |= CMediaTrackReadOptions::NONBLOCKING;
-    }
-
-    int64_t seekPosition = 0;
-    MediaTrack::ReadOptions::SeekMode seekMode;
-    if (options->getSeekTo(&seekPosition, &seekMode)) {
-        opts |= SEEK;
-        opts |= (uint32_t) seekMode;
-    }
-
-
-    return wrapper->read(wrapper->data, buffer, opts, seekPosition);
-}
-
-bool MediaTrackCUnwrapper::supportNonblockingRead() {
-    return wrapper->supportsNonBlockingRead(wrapper->data);
-}
-
-}  // namespace android
diff --git a/media/libmediaplayer2/Android.bp b/media/libmediaplayer2/Android.bp
index 2db48a4..a26cc81 100644
--- a/media/libmediaplayer2/Android.bp
+++ b/media/libmediaplayer2/Android.bp
@@ -26,7 +26,6 @@
         "libutils",
 
         "libcrypto",
-        "libmediadrm",
         "libmediametrics",
         "libmediandk",
         "libmediautils",
diff --git a/media/libmediaplayer2/nuplayer2/Android.bp b/media/libmediaplayer2/nuplayer2/Android.bp
index 7cf4522..26da491 100644
--- a/media/libmediaplayer2/nuplayer2/Android.bp
+++ b/media/libmediaplayer2/nuplayer2/Android.bp
@@ -48,7 +48,6 @@
         "libui",
         "libgui",
         "libmedia",
-        "libmediadrm",
         "libmediandk",
         "libpowermanager",
     ],
diff --git a/media/libstagefright/ACodec.cpp b/media/libstagefright/ACodec.cpp
index 68adf3c..f720667 100644
--- a/media/libstagefright/ACodec.cpp
+++ b/media/libstagefright/ACodec.cpp
@@ -5384,7 +5384,7 @@
         AudioEncoding pcmEncoding = kAudioEncodingPcm16bit;
         (void)mConfigFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
         AudioEncoding codecPcmEncoding = kAudioEncodingPcm16bit;
-        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&pcmEncoding);
+        (void)mOutputFormat->findInt32("pcm-encoding", (int32_t*)&codecPcmEncoding);
 
         mConverter[kPortIndexOutput] = AudioConverter::Create(codecPcmEncoding, pcmEncoding);
         if (mConverter[kPortIndexOutput] != NULL) {
diff --git a/media/libstagefright/Android.bp b/media/libstagefright/Android.bp
index 4127818..90a7eb5 100644
--- a/media/libstagefright/Android.bp
+++ b/media/libstagefright/Android.bp
@@ -124,6 +124,7 @@
         "MediaExtractor.cpp",
         "MediaExtractorFactory.cpp",
         "MediaSync.cpp",
+        "MediaTrack.cpp",
         "http/ClearMediaHTTP.cpp",
         "http/MediaHTTP.cpp",
         "MediaMuxer.cpp",
diff --git a/media/libstagefright/MediaExtractor.cpp b/media/libstagefright/MediaExtractor.cpp
index 6710121..e00c3c8 100644
--- a/media/libstagefright/MediaExtractor.cpp
+++ b/media/libstagefright/MediaExtractor.cpp
@@ -22,7 +22,8 @@
 #include <media/stagefright/foundation/ADebug.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <media/stagefright/MetaData.h>
-#include <media/MediaTrack.h>
+#include <media/stagefright/Utils.h>
+#include <media/NdkMediaFormatPriv.h>
 
 namespace android {
 
@@ -41,42 +42,95 @@
 }
 
 // --------------------------------------------------------------------------------
-MediaExtractorCUnwrapper::MediaExtractorCUnwrapper(CMediaExtractor *wrapper) {
-    this->wrapper = wrapper;
+MediaExtractorCUnwrapperV1::MediaExtractorCUnwrapperV1(CMediaExtractor *plugin) {
+    this->plugin = plugin;
 }
 
-MediaExtractorCUnwrapper::~MediaExtractorCUnwrapper() {
-    wrapper->free(wrapper->data);
-    free(wrapper);
+MediaExtractorCUnwrapperV1::~MediaExtractorCUnwrapperV1() {
+    plugin->free(plugin->data);
+    free(plugin);
 }
 
-size_t MediaExtractorCUnwrapper::countTracks() {
-    return wrapper->countTracks(wrapper->data);
+size_t MediaExtractorCUnwrapperV1::countTracks() {
+    return plugin->countTracks(plugin->data);
 }
 
-MediaTrack *MediaExtractorCUnwrapper::getTrack(size_t index) {
-    return new MediaTrackCUnwrapper(wrapper->getTrack(wrapper->data, index));
+MediaTrack *MediaExtractorCUnwrapperV1::getTrack(size_t index) {
+    return new MediaTrackCUnwrapper(plugin->getTrack(plugin->data, index));
 }
 
-status_t MediaExtractorCUnwrapper::getTrackMetaData(
+status_t MediaExtractorCUnwrapperV1::getTrackMetaData(
         MetaDataBase& meta, size_t index, uint32_t flags) {
-    return wrapper->getTrackMetaData(wrapper->data, meta, index, flags);
+    return plugin->getTrackMetaData(plugin->data, meta, index, flags);
 }
 
-status_t MediaExtractorCUnwrapper::getMetaData(MetaDataBase& meta) {
-    return wrapper->getMetaData(wrapper->data, meta);
+status_t MediaExtractorCUnwrapperV1::getMetaData(MetaDataBase& meta) {
+    return plugin->getMetaData(plugin->data, meta);
 }
 
-const char * MediaExtractorCUnwrapper::name() {
-    return wrapper->name(wrapper->data);
+const char * MediaExtractorCUnwrapperV1::name() {
+    return plugin->name(plugin->data);
 }
 
-uint32_t MediaExtractorCUnwrapper::flags() const {
-    return wrapper->flags(wrapper->data);
+uint32_t MediaExtractorCUnwrapperV1::flags() const {
+    return plugin->flags(plugin->data);
 }
 
-status_t MediaExtractorCUnwrapper::setMediaCas(const uint8_t* casToken, size_t size) {
-    return wrapper->setMediaCas(wrapper->data, casToken, size);
+status_t MediaExtractorCUnwrapperV1::setMediaCas(const uint8_t* casToken, size_t size) {
+    return plugin->setMediaCas(plugin->data, casToken, size);
+}
+
+// --------------------------------------------------------------------------------
+MediaExtractorCUnwrapperV2::MediaExtractorCUnwrapperV2(CMediaExtractorV2 *plugin) {
+    this->plugin = plugin;
+}
+
+MediaExtractorCUnwrapperV2::~MediaExtractorCUnwrapperV2() {
+    plugin->free(plugin->data);
+    free(plugin);
+}
+
+size_t MediaExtractorCUnwrapperV2::countTracks() {
+    return plugin->countTracks(plugin->data);
+}
+
+MediaTrack *MediaExtractorCUnwrapperV2::getTrack(size_t index) {
+    return new MediaTrackCUnwrapperV2(plugin->getTrack(plugin->data, index));
+}
+
+status_t MediaExtractorCUnwrapperV2::getTrackMetaData(
+        MetaDataBase& meta, size_t index, uint32_t flags) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *format =  AMediaFormat_fromMsg(&msg);
+    status_t ret = plugin->getTrackMetaData(plugin->data, format, index, flags);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete format;
+    meta = *newMeta;
+    return ret;
+}
+
+status_t MediaExtractorCUnwrapperV2::getMetaData(MetaDataBase& meta) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *format =  AMediaFormat_fromMsg(&msg);
+    status_t ret = plugin->getMetaData(plugin->data, format);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete format;
+    meta = *newMeta;
+    return ret;
+}
+
+const char * MediaExtractorCUnwrapperV2::name() {
+    return plugin->name(plugin->data);
+}
+
+uint32_t MediaExtractorCUnwrapperV2::flags() const {
+    return plugin->flags(plugin->data);
+}
+
+status_t MediaExtractorCUnwrapperV2::setMediaCas(const uint8_t* casToken, size_t size) {
+    return plugin->setMediaCas(plugin->data, casToken, size);
 }
 
 }  // namespace android
diff --git a/media/libstagefright/MediaExtractorFactory.cpp b/media/libstagefright/MediaExtractorFactory.cpp
index f1c6acd..8f1dd36 100644
--- a/media/libstagefright/MediaExtractorFactory.cpp
+++ b/media/libstagefright/MediaExtractorFactory.cpp
@@ -74,22 +74,32 @@
     source->DrmInitialization(nullptr /* mime */);
 
     void *meta = nullptr;
-    CreatorFunc creator = NULL;
+    void *creator = NULL;
     FreeMetaFunc freeMeta = nullptr;
     float confidence;
     sp<ExtractorPlugin> plugin;
-    creator = sniff(source, &confidence, &meta, &freeMeta, plugin);
+    uint32_t creatorVersion = 0;
+    creator = sniff(source, &confidence, &meta, &freeMeta, plugin, &creatorVersion);
     if (!creator) {
         ALOGV("FAILED to autodetect media content.");
         return NULL;
     }
 
-    CMediaExtractor *ret = creator(source->wrap(), meta);
-    if (meta != nullptr && freeMeta != nullptr) {
-        freeMeta(meta);
+    MediaExtractor *ex = nullptr;
+    if (creatorVersion == 1) {
+        CMediaExtractor *ret = ((CreatorFuncV1)creator)(source->wrap(), meta);
+        if (meta != nullptr && freeMeta != nullptr) {
+            freeMeta(meta);
+        }
+        ex = ret != nullptr ? new MediaExtractorCUnwrapperV1(ret) : nullptr;
+    } else if (creatorVersion == 2) {
+        CMediaExtractorV2 *ret = ((CreatorFuncV2)creator)(source->wrap(), meta);
+        if (meta != nullptr && freeMeta != nullptr) {
+            freeMeta(meta);
+        }
+        ex = ret != nullptr ? new MediaExtractorCUnwrapperV2(ret) : nullptr;
     }
 
-    MediaExtractor *ex = ret != nullptr ? new MediaExtractorCUnwrapper(ret) : nullptr;
     ALOGV("Created an extractor '%s' with confidence %.2f",
          ex != nullptr ? ex->name() : "<null>", confidence);
 
@@ -129,9 +139,9 @@
 bool MediaExtractorFactory::gIgnoreVersion = false;
 
 // static
-CreatorFunc MediaExtractorFactory::sniff(
+void *MediaExtractorFactory::sniff(
         const sp<DataSource> &source, float *confidence, void **meta,
-        FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin) {
+        FreeMetaFunc *freeMeta, sp<ExtractorPlugin> &plugin, uint32_t *creatorVersion) {
     *confidence = 0.0f;
     *meta = nullptr;
 
@@ -144,15 +154,23 @@
         plugins = gPlugins;
     }
 
-    CreatorFunc curCreator = NULL;
-    CreatorFunc bestCreator = NULL;
+    void *bestCreator = NULL;
     for (auto it = plugins->begin(); it != plugins->end(); ++it) {
         ALOGV("sniffing %s", (*it)->def.extractor_name);
         float newConfidence;
         void *newMeta = nullptr;
         FreeMetaFunc newFreeMeta = nullptr;
-        if ((curCreator = (*it)->def.sniff(
-                        source->wrap(), &newConfidence, &newMeta, &newFreeMeta))) {
+
+        void *curCreator = NULL;
+        if ((*it)->def.def_version == 1) {
+            curCreator = (void*) (*it)->def.sniff.v1(
+                    source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
+        } else if ((*it)->def.def_version == 2) {
+            curCreator = (void*) (*it)->def.sniff.v2(
+                    source->wrap(), &newConfidence, &newMeta, &newFreeMeta);
+        }
+
+        if (curCreator) {
             if (newConfidence > *confidence) {
                 *confidence = newConfidence;
                 if (*meta != nullptr && *freeMeta != nullptr) {
@@ -162,6 +180,7 @@
                 *freeMeta = newFreeMeta;
                 plugin = *it;
                 bestCreator = curCreator;
+                *creatorVersion = (*it)->def.def_version;
             } else {
                 if (newMeta != nullptr && newFreeMeta != nullptr) {
                     newFreeMeta(newMeta);
@@ -178,7 +197,7 @@
         std::list<sp<ExtractorPlugin>> &pluginList) {
     // sanity check check struct version, uuid, name
     if (plugin->def.def_version == 0
-            || plugin->def.def_version > EXTRACTORDEF_VERSION) {
+            || plugin->def.def_version > EXTRACTORDEF_VERSION_CURRENT) {
         ALOGE("don't understand extractor format %u, ignoring.", plugin->def.def_version);
         return;
     }
@@ -337,8 +356,9 @@
     out.append("Available extractors:\n");
     if (gPluginsRegistered) {
         for (auto it = gPlugins->begin(); it != gPlugins->end(); ++it) {
-            out.appendFormat("  %25s: uuid(%s), version(%u), path(%s)\n",
+            out.appendFormat("  %25s: plugin_version(%d), uuid(%s), version(%u), path(%s)\n",
                     (*it)->def.extractor_name,
+                    (*it)->def.def_version,
                     (*it)->uuidString.c_str(),
                     (*it)->def.extractor_version,
                     (*it)->libPath.c_str());
diff --git a/media/libstagefright/MediaTrack.cpp b/media/libstagefright/MediaTrack.cpp
new file mode 100644
index 0000000..792b317
--- /dev/null
+++ b/media/libstagefright/MediaTrack.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright (C) 2009 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <mutex>
+
+#include <media/stagefright/foundation/AMessage.h>
+#include <media/stagefright/Utils.h>
+
+#include <media/MediaTrack.h>
+#include <media/MediaExtractorPluginApi.h>
+#include <media/NdkMediaFormatPriv.h>
+
+namespace android {
+
+MediaTrack::MediaTrack() {}
+
+MediaTrack::~MediaTrack() {}
+
+////////////////////////////////////////////////////////////////////////////////
+
+void MediaTrack::ReadOptions::setNonBlocking() {
+    mNonBlocking = true;
+}
+
+void MediaTrack::ReadOptions::clearNonBlocking() {
+    mNonBlocking = false;
+}
+
+bool MediaTrack::ReadOptions::getNonBlocking() const {
+    return mNonBlocking;
+}
+
+void MediaTrack::ReadOptions::setSeekTo(int64_t time_us, SeekMode mode) {
+    mOptions |= kSeekTo_Option;
+    mSeekTimeUs = time_us;
+    mSeekMode = mode;
+}
+
+bool MediaTrack::ReadOptions::getSeekTo(
+        int64_t *time_us, SeekMode *mode) const {
+    *time_us = mSeekTimeUs;
+    *mode = mSeekMode;
+    return (mOptions & kSeekTo_Option) != 0;
+}
+
+/* -------------- unwrapper v1 --------------- */
+
+MediaTrackCUnwrapper::MediaTrackCUnwrapper(CMediaTrack *cmediatrack) {
+    wrapper = cmediatrack;
+}
+
+MediaTrackCUnwrapper::~MediaTrackCUnwrapper() {
+    wrapper->free(wrapper->data);
+    free(wrapper);
+}
+
+status_t MediaTrackCUnwrapper::start(MetaDataBase *params) {
+    return wrapper->start(wrapper->data, params);
+}
+
+status_t MediaTrackCUnwrapper::stop() {
+    return wrapper->stop(wrapper->data);
+}
+
+status_t MediaTrackCUnwrapper::getFormat(MetaDataBase& format) {
+    return wrapper->getFormat(wrapper->data, format);
+}
+
+status_t MediaTrackCUnwrapper::read(MediaBufferBase **buffer, const ReadOptions *options) {
+
+    uint32_t opts = 0;
+
+    if (options->getNonBlocking()) {
+        opts |= CMediaTrackReadOptions::NONBLOCKING;
+    }
+
+    int64_t seekPosition = 0;
+    MediaTrack::ReadOptions::SeekMode seekMode;
+    if (options->getSeekTo(&seekPosition, &seekMode)) {
+        opts |= SEEK;
+        opts |= (uint32_t) seekMode;
+    }
+
+
+    return wrapper->read(wrapper->data, buffer, opts, seekPosition);
+}
+
+bool MediaTrackCUnwrapper::supportNonblockingRead() {
+    return wrapper->supportsNonBlockingRead(wrapper->data);
+}
+
+/* -------------- unwrapper v2 --------------- */
+
+MediaTrackCUnwrapperV2::MediaTrackCUnwrapperV2(CMediaTrackV2 *cmediatrack2) {
+    wrapper = cmediatrack2;
+}
+
+MediaTrackCUnwrapperV2::~MediaTrackCUnwrapperV2() {
+}
+
+status_t MediaTrackCUnwrapperV2::start(MetaDataBase *meta) {
+    sp<AMessage> msg;
+    convertMetaDataToMessage(meta, &msg);
+    AMediaFormat *format =  AMediaFormat_fromMsg(&msg);
+    status_t ret = wrapper->start(wrapper->data, format);
+    delete format;
+    return ret;
+}
+
+status_t MediaTrackCUnwrapperV2::stop() {
+    return wrapper->stop(wrapper->data);
+}
+
+status_t MediaTrackCUnwrapperV2::getFormat(MetaDataBase& format) {
+    sp<AMessage> msg = new AMessage();
+    AMediaFormat *tmpFormat =  AMediaFormat_fromMsg(&msg);
+    status_t ret = wrapper->getFormat(wrapper->data, tmpFormat);
+    sp<MetaData> newMeta = new MetaData();
+    convertMessageToMetaData(msg, newMeta);
+    delete tmpFormat;
+    format = *newMeta;
+    return ret;
+}
+
+status_t MediaTrackCUnwrapperV2::read(MediaBufferBase **buffer, const ReadOptions *options) {
+
+    uint32_t opts = 0;
+
+    if (options->getNonBlocking()) {
+        opts |= CMediaTrackReadOptions::NONBLOCKING;
+    }
+
+    int64_t seekPosition = 0;
+    MediaTrack::ReadOptions::SeekMode seekMode;
+    if (options->getSeekTo(&seekPosition, &seekMode)) {
+        opts |= SEEK;
+        opts |= (uint32_t) seekMode;
+    }
+
+    return wrapper->read(wrapper->data, buffer, opts, seekPosition);
+}
+
+bool MediaTrackCUnwrapperV2::supportNonblockingRead() {
+    return wrapper->supportsNonBlockingRead(wrapper->data);
+}
+
+}  // namespace android
diff --git a/media/libstagefright/Utils.cpp b/media/libstagefright/Utils.cpp
index ada37a6..ebc3b33 100644
--- a/media/libstagefright/Utils.cpp
+++ b/media/libstagefright/Utils.cpp
@@ -74,7 +74,7 @@
 }
 #endif
 
-static void convertMetaDataToMessageColorAspects(const sp<MetaData> &meta, sp<AMessage> &msg) {
+static void convertMetaDataToMessageColorAspects(const MetaDataBase *meta, sp<AMessage> &msg) {
     // 0 values are unspecified
     int32_t range = 0;
     int32_t primaries = 0;
@@ -568,8 +568,14 @@
     }
 }
 
+
 status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format) {
+    return convertMetaDataToMessage(meta.get(), format);
+}
+
+status_t convertMetaDataToMessage(
+        const MetaDataBase *meta, sp<AMessage> *format) {
 
     format->clear();
 
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
index bc0a69f..d393c7a 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.cpp
@@ -147,7 +147,7 @@
     mEndOfOutput = false;
     mOutputDelayCompensated = 0;
     mOutputDelayRingBufferSize = 2048 * MAX_CHANNEL_COUNT * kNumDelayBlocksMax;
-    mOutputDelayRingBuffer = new short[mOutputDelayRingBufferSize];
+    mOutputDelayRingBuffer = new int16_t[mOutputDelayRingBufferSize];
     mOutputDelayRingBufferWritePos = 0;
     mOutputDelayRingBufferReadPos = 0;
     mOutputDelayRingBufferFilled = 0;
diff --git a/media/libstagefright/codecs/aacdec/SoftAAC2.h b/media/libstagefright/codecs/aacdec/SoftAAC2.h
index 73a3965..5bee710 100644
--- a/media/libstagefright/codecs/aacdec/SoftAAC2.h
+++ b/media/libstagefright/codecs/aacdec/SoftAAC2.h
@@ -81,7 +81,7 @@
     bool mEndOfOutput;
     int32_t mOutputDelayCompensated;
     int32_t mOutputDelayRingBufferSize;
-    short *mOutputDelayRingBuffer;
+    int16_t *mOutputDelayRingBuffer;
     int32_t mOutputDelayRingBufferWritePos;
     int32_t mOutputDelayRingBufferReadPos;
     int32_t mOutputDelayRingBufferFilled;
diff --git a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
index b8cfefa..ddc818e 100644
--- a/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
+++ b/media/libstagefright/codecs/amrwb/src/pvamrwbdecoder.cpp
@@ -455,7 +455,7 @@
                              &exc2[i_subfr],
                              0,
                              &synth16k[i_subfr *5/4],
-                             (short) 1,
+                             1,
                              HfIsf,
                              nb_bits,
                              newDTXState,
diff --git a/media/libstagefright/codecs/common/include/voType.h b/media/libstagefright/codecs/common/include/voType.h
index da208d4..73f24d0 100644
--- a/media/libstagefright/codecs/common/include/voType.h
+++ b/media/libstagefright/codecs/common/include/voType.h
@@ -22,6 +22,8 @@
 #ifndef __voType_H__
 #define __voType_H__
 
+#include <stdint.h>
+
 #ifdef __cplusplus
 extern "C" {
 #endif /* __cplusplus */
@@ -62,28 +64,28 @@
 typedef void VO_VOID;
 
 /** VO_U8 is an 8 bit unsigned quantity that is byte aligned */
-typedef unsigned char VO_U8;
+typedef uint8_t VO_U8;
 
 /** VO_BYTE is an 8 bit unsigned quantity that is byte aligned */
-typedef unsigned char VO_BYTE;
+typedef uint8_t VO_BYTE;
 
 /** VO_S8 is an 8 bit signed quantity that is byte aligned */
-typedef signed char VO_S8;
+typedef int8_t VO_S8;
 
 /** VO_CHAR is an 8 bit signed quantity that is byte aligned */
-typedef char VO_CHAR;
+typedef int8_t VO_CHAR;
 
 /** VO_U16 is a 16 bit unsigned quantity that is 16 bit word aligned */
-typedef unsigned short VO_U16;
+typedef uint16_t VO_U16;
 
 /** VO_S16 is a 16 bit signed quantity that is 16 bit word aligned */
-typedef signed short VO_S16;
+typedef int16_t VO_S16;
 
 /** VO_U32 is a 32 bit unsigned quantity that is 32 bit word aligned */
-typedef unsigned long VO_U32;
+typedef uint32_t VO_U32;
 
 /** VO_S32 is a 32 bit signed quantity that is 32 bit word aligned */
-typedef signed long VO_S32;
+typedef int32_t VO_S32;
 
 /* Users with compilers that cannot accept the "long long" designation should
    define the VO_SKIP64BIT macro.  It should be noted that this may cause
@@ -94,14 +96,14 @@
 #ifndef VO_SKIP64BIT
 #ifdef _MSC_VER
 /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
-typedef unsigned __int64  VO_U64;
+typedef uint64_t  VO_U64;
 /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
-typedef signed   __int64  VO_S64;
+typedef int64_t  VO_S64;
 #else // WIN32
 /** VO_U64 is a 64 bit unsigned quantity that is 64 bit word aligned */
-typedef unsigned long long VO_U64;
+typedef uint64_t VO_U64;
 /** VO_S64 is a 64 bit signed quantity that is 64 bit word aligned */
-typedef signed long long VO_S64;
+typedef int64_t VO_S64;
 #endif // WIN32
 #endif // VO_SKIP64BIT
 
diff --git a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
index 2c0f224..4db0060 100644
--- a/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
+++ b/media/libstagefright/codecs/flac/dec/SoftFlacDecoder.cpp
@@ -305,7 +305,7 @@
     while ((!inQueue.empty() || mSawInputEOS) && !outQueue.empty() && !mFinishedDecoder) {
         BufferInfo *outInfo = *outQueue.begin();
         OMX_BUFFERHEADERTYPE *outHeader = outInfo->mHeader;
-        short *outBuffer = reinterpret_cast<short *>(outHeader->pBuffer + outHeader->nOffset);
+        int16_t *outBuffer = reinterpret_cast<int16_t *>(outHeader->pBuffer + outHeader->nOffset);
         size_t outBufferSize = outHeader->nAllocLen - outHeader->nOffset;
         int64_t timeStamp = 0;
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
index 9451479..d5a3ff1 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/include/mp4enc_api.h
@@ -18,16 +18,17 @@
 #ifndef _MP4ENC_API_H_
 #define _MP4ENC_API_H_
 
+#include <stdint.h>
 #include <string.h>
 
 #ifndef _PV_TYPES_
 #define _PV_TYPES_
-typedef unsigned char UChar;
-typedef char Char;
+typedef uint8_t UChar;
+typedef int8_t Char;
 typedef unsigned int UInt;
 typedef int Int;
-typedef unsigned short UShort;
-typedef short Short;
+typedef uint16_t UShort;
+typedef int16_t Short;
 typedef unsigned int Bool;
 typedef uint32_t ULong;
 
diff --git a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
index 2d44482..dbd70dc 100644
--- a/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
+++ b/media/libstagefright/codecs/m4v_h263/enc/src/mp4def.h
@@ -52,13 +52,13 @@
 
 #ifndef _PV_TYPES_
 #define _PV_TYPES_
-typedef unsigned char UChar;
-typedef char Char;
+typedef uint8_t UChar;
+typedef int8_t Char;
 typedef unsigned int UInt;
 typedef int Int;
-typedef unsigned short UShort;
-typedef short Short;
-typedef short int SInt;
+typedef uint16_t UShort;
+typedef int16_t Short;
+typedef int16_t SInt;
 typedef unsigned int Bool;
 typedef uint32_t ULong;
 typedef void Void;
diff --git a/media/libstagefright/flac/dec/FLACDecoder.cpp b/media/libstagefright/flac/dec/FLACDecoder.cpp
index a2b6ab7..dfdc41c 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.cpp
+++ b/media/libstagefright/flac/dec/FLACDecoder.cpp
@@ -120,7 +120,7 @@
 // Copy samples from FLAC native 32-bit non-interleaved to 16-bit interleaved.
 // These are candidates for optimization if needed.
 static void copyMono8(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -130,7 +130,7 @@
 }
 
 static void copyStereo8(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -141,7 +141,7 @@
 }
 
 static void copyMultiCh8(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned nChannels) {
@@ -153,7 +153,7 @@
 }
 
 static void copyMono16(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -163,7 +163,7 @@
 }
 
 static void copyStereo16(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -174,7 +174,7 @@
 }
 
 static void copyMultiCh16(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned nChannels) {
@@ -187,7 +187,7 @@
 
 // TODO: 24-bit versions should do dithering or noise-shaping, here or in AudioFlinger
 static void copyMono24(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -197,7 +197,7 @@
 }
 
 static void copyStereo24(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned /* nChannels */) {
@@ -208,7 +208,7 @@
 }
 
 static void copyMultiCh24(
-        short *dst,
+        int16_t *dst,
         const int * src[FLACDecoder::kMaxChannels],
         unsigned nSamples,
         unsigned nChannels) {
@@ -391,7 +391,7 @@
     static const struct {
         unsigned mChannels;
         unsigned mBitsPerSample;
-        void (*mCopy)(short *dst, const int * src[kMaxChannels],
+        void (*mCopy)(int16_t *dst, const int * src[kMaxChannels],
                 unsigned nSamples, unsigned nChannels);
     } table[] = {
         { 1,  8, copyMono8     },
@@ -420,7 +420,7 @@
 }
 
 status_t FLACDecoder::decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
-        short *outBuffer, size_t *outBufferLen) {
+        int16_t *outBuffer, size_t *outBufferLen) {
     ALOGV("decodeOneFrame: input size(%zu)", inBufferLen);
 
     if (!mStreamInfoValid) {
@@ -469,12 +469,12 @@
         return ERROR_MALFORMED;
     }
 
-    size_t bufferSize = blocksize * getChannels() * sizeof(short);
+    size_t bufferSize = blocksize * getChannels() * sizeof(int16_t);
     if (bufferSize > *outBufferLen) {
         ALOGW("decodeOneFrame: output buffer holds only partial frame %zu:%zu",
                 *outBufferLen, bufferSize);
-        blocksize = *outBufferLen / (getChannels() * sizeof(short));
-        bufferSize = blocksize * getChannels() * sizeof(short);
+        blocksize = *outBufferLen / (getChannels() * sizeof(int16_t));
+        bufferSize = blocksize * getChannels() * sizeof(int16_t);
     }
 
     if (mCopy == nullptr) {
diff --git a/media/libstagefright/flac/dec/FLACDecoder.h b/media/libstagefright/flac/dec/FLACDecoder.h
index 1a33cae..af419a2 100644
--- a/media/libstagefright/flac/dec/FLACDecoder.h
+++ b/media/libstagefright/flac/dec/FLACDecoder.h
@@ -41,7 +41,7 @@
 
     status_t parseMetadata(const uint8_t *inBuffer, size_t inBufferLen);
     status_t decodeOneFrame(const uint8_t *inBuffer, size_t inBufferLen,
-            short *outBuffer, size_t *outBufferLen);
+            int16_t *outBuffer, size_t *outBufferLen);
     void flush();
     virtual ~FLACDecoder();
 
@@ -89,7 +89,7 @@
     // most recent error reported by libFLAC decoder
     FLAC__StreamDecoderErrorStatus mErrorStatus;
 
-    void (*mCopy)(short *dst, const int *src[kMaxChannels], unsigned nSamples, unsigned nChannels);
+    void (*mCopy)(int16_t *dst, const int *src[kMaxChannels], unsigned nSamples, unsigned nChannels);
 
     status_t init();
 
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index 3e5c905..71343d5 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -90,7 +90,22 @@
 
 class MediaExtractorCUnwrapper : public MediaExtractor {
 public:
-    explicit MediaExtractorCUnwrapper(CMediaExtractor *wrapper);
+    MediaExtractorCUnwrapper() {};
+    virtual size_t countTracks() = 0;
+    virtual MediaTrack *getTrack(size_t index) = 0;
+    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0) = 0;
+    virtual status_t getMetaData(MetaDataBase& meta) = 0;
+    virtual const char * name() = 0;
+    virtual uint32_t flags() const = 0;
+    virtual status_t setMediaCas(const uint8_t* casToken, size_t size) = 0;
+protected:
+    virtual ~MediaExtractorCUnwrapper() {};
+};
+
+
+class MediaExtractorCUnwrapperV1 : public MediaExtractorCUnwrapper {
+public:
+    explicit MediaExtractorCUnwrapperV1(CMediaExtractor *plugin);
     virtual size_t countTracks();
     virtual MediaTrack *getTrack(size_t index);
     virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0);
@@ -99,9 +114,25 @@
     virtual uint32_t flags() const;
     virtual status_t setMediaCas(const uint8_t* casToken, size_t size);
 protected:
-    virtual ~MediaExtractorCUnwrapper();
+    virtual ~MediaExtractorCUnwrapperV1();
 private:
-    CMediaExtractor *wrapper;
+    CMediaExtractor *plugin;
+};
+
+class MediaExtractorCUnwrapperV2 : public MediaExtractorCUnwrapper {
+public:
+    explicit MediaExtractorCUnwrapperV2(CMediaExtractorV2 *plugin);
+    virtual size_t countTracks();
+    virtual MediaTrack *getTrack(size_t index);
+    virtual status_t getTrackMetaData(MetaDataBase& meta, size_t index, uint32_t flags = 0);
+    virtual status_t getMetaData(MetaDataBase& meta);
+    virtual const char * name();
+    virtual uint32_t flags() const;
+    virtual status_t setMediaCas(const uint8_t* casToken, size_t size);
+protected:
+    virtual ~MediaExtractorCUnwrapperV2();
+private:
+    CMediaExtractorV2 *plugin;
 };
 
 }  // namespace android
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
index e603176..ef9f7ed 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractorFactory.h
@@ -49,9 +49,9 @@
     static void RegisterExtractor(
             const sp<ExtractorPlugin> &plugin, std::list<sp<ExtractorPlugin>> &pluginList);
 
-    static CreatorFunc sniff(const sp<DataSource> &source,
+    static void *sniff(const sp<DataSource> &source,
             float *confidence, void **meta, FreeMetaFunc *freeMeta,
-            sp<ExtractorPlugin> &plugin);
+            sp<ExtractorPlugin> &plugin, uint32_t *creatorVersion);
 
     static void UpdateExtractors(const char *newUpdateApkPath);
 };
diff --git a/media/libstagefright/include/media/stagefright/Utils.h b/media/libstagefright/include/media/stagefright/Utils.h
index 6a28e0b..46a419d 100644
--- a/media/libstagefright/include/media/stagefright/Utils.h
+++ b/media/libstagefright/include/media/stagefright/Utils.h
@@ -30,6 +30,8 @@
 
 struct AMessage;
 status_t convertMetaDataToMessage(
+        const MetaDataBase *meta, sp<AMessage> *format);
+status_t convertMetaDataToMessage(
         const sp<MetaData> &meta, sp<AMessage> *format);
 void convertMessageToMetaData(
         const sp<AMessage> &format, sp<MetaData> &meta);
diff --git a/media/ndk/NdkMediaDataSource.cpp b/media/ndk/NdkMediaDataSource.cpp
index 9ea734b..75477b4 100644
--- a/media/ndk/NdkMediaDataSource.cpp
+++ b/media/ndk/NdkMediaDataSource.cpp
@@ -48,14 +48,18 @@
     AMediaDataSourceReadAt readAt;
     AMediaDataSourceGetSize getSize;
     AMediaDataSourceClose close;
+    sp<DataSource> mImpl;
+    uint32_t mFlags;
 };
 
 NdkDataSource::NdkDataSource(AMediaDataSource *dataSource)
     : mDataSource(AMediaDataSource_new()) {
-      AMediaDataSource_setReadAt(mDataSource, dataSource->readAt);
-      AMediaDataSource_setGetSize(mDataSource, dataSource->getSize);
-      AMediaDataSource_setClose(mDataSource, dataSource->close);
-      AMediaDataSource_setUserdata(mDataSource, dataSource->userdata);
+    AMediaDataSource_setReadAt(mDataSource, dataSource->readAt);
+    AMediaDataSource_setGetSize(mDataSource, dataSource->getSize);
+    AMediaDataSource_setClose(mDataSource, dataSource->close);
+    AMediaDataSource_setUserdata(mDataSource, dataSource->userdata);
+    mDataSource->mImpl = dataSource->mImpl;
+    mDataSource->mFlags = dataSource->mFlags;
 }
 
 NdkDataSource::~NdkDataSource() {
@@ -66,9 +70,13 @@
     return OK;
 }
 
+uint32_t NdkDataSource::flags() {
+    return mDataSource->mFlags;
+}
+
 ssize_t NdkDataSource::readAt(off64_t offset, void *data, size_t size) {
     Mutex::Autolock l(mLock);
-    if (mDataSource->getSize == NULL || mDataSource->userdata == NULL) {
+    if (mDataSource->readAt == NULL || mDataSource->userdata == NULL) {
         return -1;
     }
     return mDataSource->readAt(mDataSource->userdata, offset, data, size);
@@ -204,7 +212,10 @@
     }
 
     sp<DataSource> source = DataSourceFactory::CreateFromURI(service, uri, &headers);
-    return convertDataSourceToAMediaDataSource(source);
+    AMediaDataSource* aSource = convertDataSourceToAMediaDataSource(source);
+    aSource->mImpl = source;
+    aSource->mFlags = source->flags();
+    return aSource;
 }
 
 EXPORT
@@ -235,5 +246,10 @@
     mSource->close = close;
 }
 
+EXPORT
+void AMediaDataSource_close(AMediaDataSource *mSource) {
+    return mSource->close(mSource->userdata);
+}
+
 } // extern "C"
 
diff --git a/media/ndk/NdkMediaDataSourcePriv.h b/media/ndk/NdkMediaDataSourcePriv.h
index 3b0aa59..8a5423c 100644
--- a/media/ndk/NdkMediaDataSourcePriv.h
+++ b/media/ndk/NdkMediaDataSourcePriv.h
@@ -44,6 +44,7 @@
     NdkDataSource(AMediaDataSource *);
 
     virtual status_t initCheck() const;
+    virtual uint32_t flags();
     virtual ssize_t readAt(off64_t offset, void *data, size_t size);
     virtual status_t getSize(off64_t *);
     virtual String8 toString();
diff --git a/media/ndk/NdkMediaFormat.cpp b/media/ndk/NdkMediaFormat.cpp
index a66f3b3..249c76e 100644
--- a/media/ndk/NdkMediaFormat.cpp
+++ b/media/ndk/NdkMediaFormat.cpp
@@ -35,23 +35,6 @@
 
 extern "C" {
 
-// private functions for conversion to/from AMessage
-AMediaFormat* AMediaFormat_fromMsg(const void* data) {
-    ALOGV("private ctor");
-    AMediaFormat* mData = new AMediaFormat();
-    mData->mFormat = *((sp<AMessage>*)data);
-    if (mData->mFormat == NULL) {
-        ALOGW("got NULL format");
-        mData->mFormat = new AMessage;
-    }
-    return mData;
-}
-
-void AMediaFormat_getFormat(const AMediaFormat* mData, void* dest) {
-    *((sp<AMessage>*)dest) = mData->mFormat;
-}
-
-
 /*
  * public function follow
  */
diff --git a/media/ndk/include/media/NdkMediaDataSource.h b/media/ndk/include/media/NdkMediaDataSource.h
index 021029b..297d4bc 100644
--- a/media/ndk/include/media/NdkMediaDataSource.h
+++ b/media/ndk/include/media/NdkMediaDataSource.h
@@ -43,14 +43,9 @@
 /*
  * AMediaDataSource's callbacks will be invoked on an implementation-defined thread
  * or thread pool. No guarantees are provided about which thread(s) will be used for
- * callbacks. However, it is guaranteed that AMediaDataSource's callbacks will only
- * ever be invoked by a single thread at a time.
- *
- * There will be a thread synchronization point between each call to ensure that
- * modifications to the state of your AMediaDataSource are visible to future
- * calls. This means you don't need to do your own synchronization unless you're
- * modifying the AMediaDataSource from another thread while it's being used by the
- * framework.
+ * callbacks. For example, |close| can be invoked from a different thread than the
+ * thread invoking |readAt|. As such, the Implementations of AMediaDataSource callbacks
+ * must be threadsafe.
  */
 
 /**
@@ -74,9 +69,19 @@
 typedef ssize_t (*AMediaDataSourceGetSize)(void *userdata);
 
 /**
- * Called to close the data source and release associated resources.
- * The NDK media framework guarantees that after |close| is called
- * no future callbacks will be invoked on the data source.
+ * Called to close the data source, unblock reads, and release associated
+ * resources.
+ *
+ * The NDK media framework guarantees that after the first |close| is
+ * called, no future callbacks will be invoked on the data source except
+ * for |close| itself.
+ *
+ * Closing a data source allows readAt calls that were blocked waiting
+ * for I/O data to return promptly.
+ *
+ * When using AMediaDataSource as input to AMediaExtractor, closing
+ * has the effect of unblocking slow reads inside of setDataSource
+ * and readSampleData.
  */
 typedef void (*AMediaDataSourceClose)(void *userdata);
 
@@ -161,6 +166,18 @@
 
 #endif  /*__ANDROID_API__ >= 28 */
 
+#if __ANDROID_API__ >= 29
+
+/**
+ * Close the data source, unblock reads, and release associated resources.
+ *
+ * Please refer to the definition of AMediaDataSourceClose for
+ * additional details.
+ */
+void AMediaDataSource_close(AMediaDataSource*) __INTRODUCED_IN(29);
+
+#endif  /*__ANDROID_API__ >= 29 */
+
 __END_DECLS
 
 #endif // _NDK_MEDIA_DATASOURCE_H
diff --git a/media/ndk/libmediandk.map.txt b/media/ndk/libmediandk.map.txt
index a805e87..d13edfc 100644
--- a/media/ndk/libmediandk.map.txt
+++ b/media/ndk/libmediandk.map.txt
@@ -142,6 +142,7 @@
     AMediaDataSource_setReadAt;   # introduced=28
     AMediaDataSource_setUserdata; # introduced=28
     AMediaDataSource_newUri;      # introduced=29
+    AMediaDataSource_close;       # introduced=29
     AMediaDrm_closeSession;
     AMediaDrm_createByUUID;
     AMediaDrm_decrypt;
diff --git a/services/audioflinger/AudioFlinger.cpp b/services/audioflinger/AudioFlinger.cpp
index 62fd5f7..06975ac 100644
--- a/services/audioflinger/AudioFlinger.cpp
+++ b/services/audioflinger/AudioFlinger.cpp
@@ -2500,9 +2500,7 @@
         if (recordThread != 0) {
             ALOGV("closeInput() %d", input);
 
-#if 0
             dumpToThreadLog_l(recordThread);
-#endif
 
             // If we still have effect chains, it means that a client still holds a handle
             // on at least one effect. We must either move the chain to an existing thread with the
@@ -2546,9 +2544,7 @@
             if (mmapThread == 0) {
                 return BAD_VALUE;
             }
-#if 0
             dumpToThreadLog_l(mmapThread);
-#endif
             mMmapThreads.removeItem(input);
         }
         const sp<AudioIoDescriptor> ioDesc = new AudioIoDescriptor();
diff --git a/services/audioflinger/Threads.cpp b/services/audioflinger/Threads.cpp
index 13ca912..01c5ea2 100644
--- a/services/audioflinger/Threads.cpp
+++ b/services/audioflinger/Threads.cpp
@@ -2794,22 +2794,18 @@
 void AudioFlinger::PlaybackThread::threadLoop_removeTracks(
         const Vector< sp<Track> >& tracksToRemove)
 {
-    size_t count = tracksToRemove.size();
-    if (count > 0) {
-        for (size_t i = 0 ; i < count ; i++) {
-            const sp<Track>& track = tracksToRemove.itemAt(i);
-            if (track->isExternalTrack()) {
-                AudioSystem::stopOutput(track->portId());
+    // Miscellaneous track cleanup when removed from the active list,
+    // called without Thread lock but synchronized with threadLoop processing.
 #ifdef ADD_BATTERY_DATA
-                // to track the speaker usage
-                addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
-#endif
-                if (track->isTerminated()) {
-                    AudioSystem::releaseOutput(track->portId());
-                }
-            }
+    for (const auto& track : tracksToRemove) {
+        if (track->isExternalTrack()) {
+            // to track the speaker usage
+            addBatteryData(IMediaPlayerService::kBatteryDataAudioFlingerStop);
         }
     }
+#else
+    (void)tracksToRemove; // suppress unused warning
+#endif
 }
 
 void AudioFlinger::PlaybackThread::checkSilentMode_l()
@@ -3710,24 +3706,28 @@
 // removeTracks_l() must be called with ThreadBase::mLock held
 void AudioFlinger::PlaybackThread::removeTracks_l(const Vector< sp<Track> >& tracksToRemove)
 {
-    size_t count = tracksToRemove.size();
-    if (count > 0) {
-        for (size_t i=0 ; i<count ; i++) {
-            const sp<Track>& track = tracksToRemove.itemAt(i);
-            mActiveTracks.remove(track);
-            ALOGV("removeTracks_l removing track on session %d", track->sessionId());
-            sp<EffectChain> chain = getEffectChain_l(track->sessionId());
-            if (chain != 0) {
-                ALOGV("stopping track on chain %p for session Id: %d", chain.get(),
-                        track->sessionId());
-                chain->decActiveTrackCnt();
-            }
+    for (const auto& track : tracksToRemove) {
+        mActiveTracks.remove(track);
+        ALOGV("%s(%d): removing track on session %d", __func__, track->id(), track->sessionId());
+        sp<EffectChain> chain = getEffectChain_l(track->sessionId());
+        if (chain != 0) {
+            ALOGV("%s(%d): stopping track on chain %p for session Id: %d",
+                    __func__, track->id(), chain.get(), track->sessionId());
+            chain->decActiveTrackCnt();
+        }
+        // If an external client track, inform APM we're no longer active, and remove if needed.
+        // We do this under lock so that the state is consistent if the Track is destroyed.
+        if (track->isExternalTrack()) {
+            AudioSystem::stopOutput(track->portId());
             if (track->isTerminated()) {
-                removeTrack_l(track);
+                AudioSystem::releaseOutput(track->portId());
             }
         }
+        if (track->isTerminated()) {
+            // remove from our tracks vector
+            removeTrack_l(track);
+        }
     }
-
 }
 
 status_t AudioFlinger::PlaybackThread::getTimestamp_l(AudioTimestamp& timestamp)
@@ -4115,12 +4115,6 @@
     return latency;
 }
 
-
-void AudioFlinger::MixerThread::threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove)
-{
-    PlaybackThread::threadLoop_removeTracks(tracksToRemove);
-}
-
 ssize_t AudioFlinger::MixerThread::threadLoop_write()
 {
     // FIXME we should only do one push per cycle; confirm this is true
diff --git a/services/audioflinger/Threads.h b/services/audioflinger/Threads.h
index 88c6ff3..61f7baf 100644
--- a/services/audioflinger/Threads.h
+++ b/services/audioflinger/Threads.h
@@ -1137,7 +1137,6 @@
     virtual     void        threadLoop_standby();
     virtual     void        threadLoop_mix();
     virtual     void        threadLoop_sleepTime();
-    virtual     void        threadLoop_removeTracks(const Vector< sp<Track> >& tracksToRemove);
     virtual     uint32_t    correctLatency_l(uint32_t latency) const;
 
     virtual     status_t    createAudioPatch_l(const struct audio_patch *patch,
diff --git a/services/audiopolicy/service/AudioPolicyService.cpp b/services/audiopolicy/service/AudioPolicyService.cpp
index 8bca221..b1ed522 100644
--- a/services/audiopolicy/service/AudioPolicyService.cpp
+++ b/services/audiopolicy/service/AudioPolicyService.cpp
@@ -677,21 +677,27 @@
                     VolumeData *data = (VolumeData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set volume stream %d, \
                             volume %f, output %d", data->mStream, data->mVolume, data->mIO);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setStreamVolume(data->mStream,
                                                                     data->mVolume,
                                                                     data->mIO);
+                    mLock.lock();
                     }break;
                 case SET_PARAMETERS: {
                     ParametersData *data = (ParametersData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set parameters string %s, io %d",
                             data->mKeyValuePairs.string(), data->mIO);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setParameters(data->mIO, data->mKeyValuePairs);
+                    mLock.lock();
                     }break;
                 case SET_VOICE_VOLUME: {
                     VoiceVolumeData *data = (VoiceVolumeData *)command->mParam.get();
                     ALOGV("AudioCommandThread() processing set voice volume volume %f",
                             data->mVolume);
+                    mLock.unlock();
                     command->mStatus = AudioSystem::setVoiceVolume(data->mVolume);
+                    mLock.lock();
                     }break;
                 case STOP_OUTPUT: {
                     StopOutputData *data = (StopOutputData *)command->mParam.get();
@@ -724,7 +730,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->createAudioPatch(&data->mPatch, &data->mHandle);
+                        mLock.lock();
                     }
                     } break;
                 case RELEASE_AUDIO_PATCH: {
@@ -734,7 +742,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->releaseAudioPatch(data->mHandle);
+                        mLock.lock();
                     }
                     } break;
                 case UPDATE_AUDIOPORT_LIST: {
@@ -764,7 +774,9 @@
                     if (af == 0) {
                         command->mStatus = PERMISSION_DENIED;
                     } else {
+                        mLock.unlock();
                         command->mStatus = af->setAudioPortConfig(&data->mConfig);
+                        mLock.lock();
                     }
                     } break;
                 case DYN_POLICY_MIX_STATE_UPDATE: {