From 50255a92dfb2ffd35955035ae9ac9d4b85f606b8 Mon Sep 17 00:00:00 2001 From: Jeff Tinker Date: Mon, 27 Jun 2011 10:48:26 -0700 Subject: Fix for b/4165024: Serious Memory leak when playing a WV protected streaming video. This change allows the WVM extractor to close and reopen when not in use which resolves the issue with heap fragmentation between plays. Change-Id: I160ee1e98aada2bfdd0818eeb6300ad50644fb75 --- media/libstagefright/WVMExtractor.cpp | 36 ++++++++++++++++++++++------------- 1 file changed, 23 insertions(+), 13 deletions(-) (limited to 'media/libstagefright/WVMExtractor.cpp') 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 -/* 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 &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 @@ WVMExtractor::WVMExtractor(const sp &source) typedef WVMLoadableExtractor *(*GetInstanceFunc)(sp); GetInstanceFunc getInstanceFunc = - (GetInstanceFunc) dlsym(gVendorLibHandle, + (GetInstanceFunc) dlsym(sVendorLibHandle, "_ZN7android11GetInstanceENS_2spINS_10DataSourceEEE"); if (getInstanceFunc) { @@ -72,6 +71,17 @@ WVMExtractor::WVMExtractor(const sp &source) } 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() { -- cgit v1.1