Merge "Multiple changes to ACodec/codec tools:"
diff --git a/cmds/stagefright/stagefright.cpp b/cmds/stagefright/stagefright.cpp
index d7b1e71..656f5fd 100644
--- a/cmds/stagefright/stagefright.cpp
+++ b/cmds/stagefright/stagefright.cpp
@@ -74,8 +74,6 @@
 
 static sp<ANativeWindow> gSurface;
 
-#define USE_SURFACE_COMPOSER 0
-
 static int64_t getNowUs() {
     struct timeval tv;
     gettimeofday(&tv, NULL);
@@ -579,6 +577,7 @@
     fprintf(stderr, "       -x display a histogram of decoding times/fps "
                     "(video only)\n");
     fprintf(stderr, "       -S allocate buffers from a surface\n");
+    fprintf(stderr, "       -T allocate buffers from a surface texture\n");
 }
 
 int main(int argc, char **argv) {
@@ -590,6 +589,7 @@
     bool extractThumbnail = false;
     bool seekTest = false;
     bool useSurfaceAlloc = false;
+    bool useSurfaceTexAlloc = false;
     gNumRepetitions = 1;
     gMaxNumFrames = 0;
     gReproduceBug = -1;
@@ -604,7 +604,7 @@
     sp<LiveSession> liveSession;
 
     int res;
-    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxS")) >= 0) {
+    while ((res = getopt(argc, argv, "han:lm:b:ptsrow:kxST")) >= 0) {
         switch (res) {
             case 'a':
             {
@@ -695,6 +695,12 @@
                 break;
             }
 
+            case 'T':
+            {
+                useSurfaceTexAlloc = true;
+                break;
+            }
+
             case '?':
             case 'h':
             default:
@@ -843,34 +849,35 @@
     sp<SurfaceComposerClient> composerClient;
     sp<SurfaceControl> control;
 
-    if (useSurfaceAlloc && !audioOnly) {
-#if USE_SURFACE_COMPOSER
-        composerClient = new SurfaceComposerClient;
-        CHECK_EQ(composerClient->initCheck(), (status_t)OK);
+    if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
+        if (useSurfaceAlloc) {
+            composerClient = new SurfaceComposerClient;
+            CHECK_EQ(composerClient->initCheck(), (status_t)OK);
 
-        control = composerClient->createSurface(
-                getpid(),
-                String8("A Surface"),
-                0,
-                1280,
-                800,
-                PIXEL_FORMAT_RGB_565,
-                0);
+            control = composerClient->createSurface(
+                    String8("A Surface"),
+                    0,
+                    1280,
+                    800,
+                    PIXEL_FORMAT_RGB_565,
+                    0);
 
-        CHECK(control != NULL);
-        CHECK(control->isValid());
+            CHECK(control != NULL);
+            CHECK(control->isValid());
 
-        CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
-        CHECK_EQ(control->setLayer(30000), (status_t)OK);
-        CHECK_EQ(control->show(), (status_t)OK);
-        CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
+            CHECK_EQ(composerClient->openTransaction(), (status_t)OK);
+            CHECK_EQ(control->setLayer(30000), (status_t)OK);
+            CHECK_EQ(control->show(), (status_t)OK);
+            CHECK_EQ(composerClient->closeTransaction(), (status_t)OK);
 
-        gSurface = control->getSurface();
-        CHECK(gSurface != NULL);
-#else
-        sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
-        gSurface = new SurfaceTextureClient(texture);
-#endif
+            gSurface = control->getSurface();
+            CHECK(gSurface != NULL);
+        } else {
+            CHECK(useSurfaceTexAlloc);
+
+            sp<SurfaceTexture> texture = new SurfaceTexture(0 /* tex */);
+            gSurface = new SurfaceTextureClient(texture);
+        }
     }
 
     DataSource::RegisterDefaultSniffers();
@@ -1061,12 +1068,12 @@
         }
     }
 
-    if (useSurfaceAlloc && !audioOnly) {
+    if ((useSurfaceAlloc || useSurfaceTexAlloc) && !audioOnly) {
         gSurface.clear();
 
-#if USE_SURFACE_COMPOSER
-        composerClient->dispose();
-#endif
+        if (useSurfaceAlloc) {
+            composerClient->dispose();
+        }
     }
 
     client.disconnect();
diff --git a/media/libstagefright/WVMExtractor.cpp b/media/libstagefright/WVMExtractor.cpp
index 26eda0c..7072d58 100644
--- a/media/libstagefright/WVMExtractor.cpp
+++ b/media/libstagefright/WVMExtractor.cpp
@@ -33,26 +33,25 @@
 
 #include <utils/Errors.h>
 
-/* The extractor lifetime is short - just long enough to get
- * the media sources constructed - so the shared lib needs to remain open
- * beyond the lifetime of the extractor.  So keep the handle as a global
- * rather than a member of the extractor
- */
-void *gVendorLibHandle = NULL;
-
 namespace android {
 
-static Mutex gWVMutex;
+Mutex WVMExtractor::sMutex;
+uint32_t WVMExtractor::sActiveExtractors = 0;
+void *WVMExtractor::sVendorLibHandle = NULL;
 
 WVMExtractor::WVMExtractor(const sp<DataSource> &source)
     : mDataSource(source) {
     {
-        Mutex::Autolock autoLock(gWVMutex);
-        if (gVendorLibHandle == NULL) {
-            gVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
+        Mutex::Autolock autoLock(sMutex);
+
+        if (sVendorLibHandle == NULL) {
+            CHECK(sActiveExtractors == 0);
+            sVendorLibHandle = dlopen("libwvm.so", RTLD_NOW);
         }
 
-        if (gVendorLibHandle == NULL) {
+        sActiveExtractors++;
+
+        if (sVendorLibHandle == NULL) {
             LOGE("Failed to open libwvm.so");
             return;
         }
@@ -60,7 +59,7 @@
 
     typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp<DataSource>);
     GetInstanceFunc getInstanceFunc =
-        (GetInstanceFunc) dlsym(gVendorLibHandle,
+        (GetInstanceFunc) dlsym(sVendorLibHandle,
                 "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE");
 
     if (getInstanceFunc) {
@@ -72,6 +71,17 @@
 }
 
 WVMExtractor::~WVMExtractor() {
+    Mutex::Autolock autoLock(sMutex);
+
+    CHECK(sActiveExtractors > 0);
+    sActiveExtractors--;
+
+    // Close lib after last use
+    if (sActiveExtractors == 0) {
+        if (sVendorLibHandle != NULL)
+            dlclose(sVendorLibHandle);
+        sVendorLibHandle = NULL;
+    }
 }
 
 size_t WVMExtractor::countTracks() {
diff --git a/media/libstagefright/include/WVMExtractor.h b/media/libstagefright/include/WVMExtractor.h
index deecd25..0817bab 100644
--- a/media/libstagefright/include/WVMExtractor.h
+++ b/media/libstagefright/include/WVMExtractor.h
@@ -18,6 +18,7 @@
 
 #define WVM_EXTRACTOR_H_
 
+#include <media/stagefright/DataSource.h>
 #include <media/stagefright/MediaExtractor.h>
 #include <utils/Errors.h>
 
@@ -67,6 +68,10 @@
 
     WVMExtractor(const WVMExtractor &);
     WVMExtractor &operator=(const WVMExtractor &);
+
+    static Mutex sMutex;
+    static uint32_t sActiveExtractors;
+    static void *sVendorLibHandle;
 };
 
 }  // namespace android