have media.codec hold dlopen() codecs forever

use RTLD_NODELETE so that the any codecs are kept forever.
This dramatically shortens the time for a subsequent dlopen()
for the same library. It turns the dlclose() of that library into a NOP.

This eliminates most dlopen/dlclose cpu time as media.codec processes
the same content type without restructuring the registration and de-registration
logic that is in place.

Bug: 36727951
Change-Id: If92bc2898f8c73f89f164524daffab81da17002e
Test: getting continued video/sound across multiple invocations
diff --git a/media/libstagefright/omx/SoftOMXPlugin.cpp b/media/libstagefright/omx/SoftOMXPlugin.cpp
index fccb12b..0bc65e1 100644
--- a/media/libstagefright/omx/SoftOMXPlugin.cpp
+++ b/media/libstagefright/omx/SoftOMXPlugin.cpp
@@ -85,7 +85,21 @@
         libName.append(kComponents[i].mLibNameSuffix);
         libName.append(".so");
 
-        void *libHandle = dlopen(libName.c_str(), RTLD_NOW);
+        // RTLD_NODELETE means we keep the shared library around forever.
+        // this eliminates thrashing during sequences like loading soundpools.
+        // It also leaves the rest of the logic around the dlopen()/dlclose()
+        // calls in this file unchanged.
+        //
+        // Implications of the change:
+        // -- the codec process (where this happens) will have a slightly larger
+        //    long-term memory footprint as it accumulates the loaded shared libraries.
+        //    This is expected to be a small amount of memory.
+        // -- plugin codecs can no longer (and never should have) depend on a
+        //    free reset of any static data as the library would have crossed
+        //    a dlclose/dlopen cycle.
+        //
+
+        void *libHandle = dlopen(libName.c_str(), RTLD_NOW|RTLD_NODELETE);
 
         if (libHandle == NULL) {
             ALOGE("unable to dlopen %s: %s", libName.c_str(), dlerror());