Merge "Add MTP and PTP OS descriptors." into oc-mr1-dev
diff --git a/media/libheif/HeifDecoderImpl.cpp b/media/libheif/HeifDecoderImpl.cpp
index 115baff..4b131a7 100644
--- a/media/libheif/HeifDecoderImpl.cpp
+++ b/media/libheif/HeifDecoderImpl.cpp
@@ -401,6 +401,10 @@
                 videoFrame->getFlattenedIccData());
     }
     mFrameDecoded = true;
+
+    // Aggressive clear to avoid holding on to resources
+    mRetriever.clear();
+    mDataSource.clear();
     return true;
 }
 
diff --git a/media/libmedia/IMediaExtractor.cpp b/media/libmedia/IMediaExtractor.cpp
index 19b00f3..3c43a72 100644
--- a/media/libmedia/IMediaExtractor.cpp
+++ b/media/libmedia/IMediaExtractor.cpp
@@ -38,7 +38,8 @@
     SETMEDIACAS,
     SETUID,
     NAME,
-    GETMETRICS
+    GETMETRICS,
+    RELEASE,
 };
 
 class BpMediaExtractor : public BpInterface<IMediaExtractor> {
@@ -138,6 +139,13 @@
         ALOGV("name NOT IMPLEMENTED");
         return NULL;
     }
+
+    virtual void release() {
+        ALOGV("release");
+        Parcel data, reply;
+        data.writeInterfaceToken(BpMediaExtractor::getInterfaceDescriptor());
+        remote()->transact(RELEASE, data, &reply);
+    }
 };
 
 IMPLEMENT_META_INTERFACE(MediaExtractor, "android.media.IMediaExtractor");
@@ -215,6 +223,12 @@
             reply->writeInt32(setMediaCas(casToken));
             return OK;
         }
+        case RELEASE: {
+            ALOGV("release");
+            CHECK_INTERFACE(IMediaExtractor, data, reply);
+            release();
+            return OK;
+        }
         default:
             return BBinder::onTransact(code, data, reply, flags);
     }
diff --git a/media/libmedia/include/media/IMediaExtractor.h b/media/libmedia/include/media/IMediaExtractor.h
index 1e13b65..0ac7673 100644
--- a/media/libmedia/include/media/IMediaExtractor.h
+++ b/media/libmedia/include/media/IMediaExtractor.h
@@ -68,6 +68,8 @@
     virtual void setUID(uid_t uid)  = 0;
 
     virtual const char * name() = 0;
+
+    virtual void release() = 0;
 };
 
 
diff --git a/media/libstagefright/MPEG4Extractor.cpp b/media/libstagefright/MPEG4Extractor.cpp
index 6f59fac..a1d48c2 100644
--- a/media/libstagefright/MPEG4Extractor.cpp
+++ b/media/libstagefright/MPEG4Extractor.cpp
@@ -354,6 +354,10 @@
 }
 
 MPEG4Extractor::~MPEG4Extractor() {
+    release();
+}
+
+void MPEG4Extractor::release() {
     Track *track = mFirstTrack;
     while (track) {
         Track *next = track->next;
@@ -375,6 +379,12 @@
     for (size_t i = 0; i < mPssh.size(); i++) {
         delete [] mPssh[i].data;
     }
+    mPssh.clear();
+
+    if (mDataSource != NULL) {
+        mDataSource->close();
+        mDataSource.clear();
+    }
 }
 
 uint32_t MPEG4Extractor::flags() const {
diff --git a/media/libstagefright/StagefrightMetadataRetriever.cpp b/media/libstagefright/StagefrightMetadataRetriever.cpp
index a53897f..103da95 100644
--- a/media/libstagefright/StagefrightMetadataRetriever.cpp
+++ b/media/libstagefright/StagefrightMetadataRetriever.cpp
@@ -60,6 +60,12 @@
 StagefrightMetadataRetriever::~StagefrightMetadataRetriever() {
     ALOGV("~StagefrightMetadataRetriever()");
     clearMetadata();
+    // Explicitly release extractor before continuing with the destructor,
+    // some extractors might need to callback to close off the DataSource
+    // and we need to make sure it's still there.
+    if (mExtractor != NULL) {
+        mExtractor->release();
+    }
     if (mSource != NULL) {
         mSource->close();
     }
diff --git a/media/libstagefright/include/MPEG4Extractor.h b/media/libstagefright/include/MPEG4Extractor.h
index 4a4c538..c9d7dde 100644
--- a/media/libstagefright/include/MPEG4Extractor.h
+++ b/media/libstagefright/include/MPEG4Extractor.h
@@ -62,6 +62,7 @@
     virtual sp<MetaData> getMetaData();
     virtual uint32_t flags() const;
     virtual const char * name() { return "MPEG4Extractor"; }
+    virtual void release();
 
     // for DRM
     virtual char* getDrmTrackInfo(size_t trackID, int *len);
diff --git a/media/libstagefright/include/media/stagefright/MediaExtractor.h b/media/libstagefright/include/media/stagefright/MediaExtractor.h
index f12160b..6ec7eaf 100644
--- a/media/libstagefright/include/media/stagefright/MediaExtractor.h
+++ b/media/libstagefright/include/media/stagefright/MediaExtractor.h
@@ -72,6 +72,8 @@
 
     virtual const char * name() { return "<unspecified>"; }
 
+    virtual void release() {}
+
 protected:
     MediaExtractor();
     virtual ~MediaExtractor();
diff --git a/media/libstagefright/omx/OMXNodeInstance.cpp b/media/libstagefright/omx/OMXNodeInstance.cpp
index c749454..cc96172 100644
--- a/media/libstagefright/omx/OMXNodeInstance.cpp
+++ b/media/libstagefright/omx/OMXNodeInstance.cpp
@@ -495,6 +495,9 @@
             LOG_ALWAYS_FATAL("unknown state %s(%#x).", asString(state), state);
             break;
     }
+
+    Mutex::Autolock _l(mLock);
+
     status_t err = mOwner->freeNode(this);
 
     mDispatcher.clear();