From 7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8 Mon Sep 17 00:00:00 2001 From: The Android Open Source Project Date: Wed, 17 Dec 2008 18:05:43 -0800 Subject: Code drop from //branches/cupcake/...@124589 --- media/libmedia/mediametadataretriever.cpp | 228 +++++++++++++++--------------- 1 file changed, 117 insertions(+), 111 deletions(-) (limited to 'media/libmedia/mediametadataretriever.cpp') diff --git a/media/libmedia/mediametadataretriever.cpp b/media/libmedia/mediametadataretriever.cpp index 9cbafbc..09afc6c 100644 --- a/media/libmedia/mediametadataretriever.cpp +++ b/media/libmedia/mediametadataretriever.cpp @@ -15,168 +15,174 @@ ** limitations under the License. */ -#include - -#ifdef LOG_TAG -#undef LOG_TAG +//#define LOG_NDEBUG 0 #define LOG_TAG "MediaMetadataRetriever" -#endif +#include +#include +#include +#include #include #include namespace android { -// Factory class function in shared libpvplayer.so -typedef MediaMetadataRetrieverImpl* (*createRetriever_f)(); +// client singleton for binder interface to service +Mutex MediaMetadataRetriever::sServiceLock; +sp MediaMetadataRetriever::sService; +sp MediaMetadataRetriever::sDeathNotifier; -MediaMetadataRetrieverImpl *MediaMetadataRetriever::mRetriever = NULL; -void *MediaMetadataRetriever::mLibHandler = NULL; - -void MediaMetadataRetriever::create() +const sp& MediaMetadataRetriever::getService() { - // Load libpvplayer library once and only once. - if (!mLibHandler) { - mLibHandler = dlopen("libopencoreplayer.so", RTLD_NOW); - if (!mLibHandler) { - LOGE("setDataSource: dlopen failed on libopencoreplayer.so"); - return; + Mutex::Autolock lock(sServiceLock); + if (sService.get() == 0) { + sp sm = defaultServiceManager(); + sp binder; + do { + binder = sm->getService(String16("media.player")); + if (binder != 0) { + break; + } + LOGW("MediaPlayerService not published, waiting..."); + usleep(500000); // 0.5 s + } while(true); + if (sDeathNotifier == NULL) { + sDeathNotifier = new DeathNotifier(); } + binder->linkToDeath(sDeathNotifier); + sService = interface_cast(binder); } - - // Each time create a new MediaMetadataRetrieverImpl object. - if (mRetriever) { - delete mRetriever; - } - createRetriever_f createRetriever = reinterpret_cast(dlsym(mLibHandler, "createRetriever")); - if (!createRetriever) { - LOGE("setDataSource: dlsym failed on createRetriever in libpvplayer.so"); + LOGE_IF(sService == 0, "no MediaPlayerService!?"); + return sService; +} + +MediaMetadataRetriever::MediaMetadataRetriever() +{ + LOGV("constructor"); + const sp& service(getService()); + if (service == 0) { + LOGE("failed to obtain MediaMetadataRetrieverService"); return; } - mRetriever = createRetriever(); - if (!mRetriever) { - LOGE("setDataSource: createRetriever failed in libpvplayer.so"); + sp retriever(service->createMetadataRetriever(getpid())); + if (retriever == 0) { + LOGE("failed to create IMediaMetadataRetriever object from server"); } + mRetriever = retriever; } -status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) +MediaMetadataRetriever::~MediaMetadataRetriever() { - if (srcUrl == NULL) { - return UNKNOWN_ERROR; + LOGV("destructor"); + disconnect(); + IPCThreadState::self()->flushCommands(); +} + +void MediaMetadataRetriever::disconnect() +{ + LOGV("disconnect"); + sp retriever; + { + Mutex::Autolock _l(mLock); + retriever = mRetriever; + mRetriever.clear(); } - - if (mRetriever) { - return mRetriever->setDataSource(srcUrl); + if (retriever != 0) { + retriever->disconnect(); } - return UNKNOWN_ERROR; } -const char* MediaMetadataRetriever::extractMetadata(int keyCode) +status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) { - if (mRetriever) { - return mRetriever->extractMetadata(keyCode); + LOGV("setDataSource"); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return INVALID_OPERATION; + } + if (srcUrl == NULL) { + LOGE("data source is a null pointer"); + return UNKNOWN_ERROR; } - return NULL; + LOGV("data source (%s)", srcUrl); + return mRetriever->setDataSource(srcUrl); } -MediaAlbumArt* MediaMetadataRetriever::extractAlbumArt() +status_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) { - if (mRetriever) { - return mRetriever->extractAlbumArt(); + LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return INVALID_OPERATION; } - return NULL; + if (fd < 0 || offset < 0 || length < 0) { + LOGE("Invalid negative argument"); + return UNKNOWN_ERROR; + } + return mRetriever->setDataSource(fd, offset, length); } -SkBitmap* MediaMetadataRetriever::captureFrame() +status_t MediaMetadataRetriever::setMode(int mode) { - if (mRetriever) { - return mRetriever->captureFrame(); + LOGV("setMode(%d)", mode); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return INVALID_OPERATION; } - return NULL; + return mRetriever->setMode(mode); } -void MediaMetadataRetriever::setMode(int mode) +status_t MediaMetadataRetriever::getMode(int* mode) { - if (mRetriever) { - mRetriever->setMode(mode); + LOGV("getMode"); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return INVALID_OPERATION; } + return mRetriever->getMode(mode); } -void MediaMetadataRetriever::release() +sp MediaMetadataRetriever::captureFrame() { - if (!mLibHandler) { - dlclose(mLibHandler); - mLibHandler = NULL; - } - if (!mRetriever) { - delete mRetriever; - mRetriever = NULL; + LOGV("captureFrame"); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return NULL; } + return mRetriever->captureFrame(); } -void MediaAlbumArt::clearData() { - if (data != NULL) { - delete []data; - data = NULL; +const char* MediaMetadataRetriever::extractMetadata(int keyCode) +{ + LOGV("extractMetadata(%d)", keyCode); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return NULL; } - length = 0; + return mRetriever->extractMetadata(keyCode); } - -MediaAlbumArt::MediaAlbumArt(const char* url) +sp MediaMetadataRetriever::extractAlbumArt() { - length = 0; - data = NULL; - FILE *in = fopen(url, "r"); - if (!in) { - LOGE("extractExternalAlbumArt: Failed to open external album art url: %s.", url); - return; - } - fseek(in, 0, SEEK_END); - length = ftell(in); // Allocating buffer of size equals to the external file size. - if (length == 0 || (data = new char[length]) == NULL) { - if (length == 0) { - LOGE("extractExternalAlbumArt: External album art url: %s has a size of 0.", url); - } else if (data == NULL) { - LOGE("extractExternalAlbumArt: No enough memory for storing the retrieved album art."); - length = 0; - } - fclose(in); - return; - } - rewind(in); - if (fread(data, 1, length, in) != length) { // Read failed. - length = 0; - delete []data; - data = NULL; - LOGE("extractExternalAlbumArt: Failed to retrieve the contents of an external album art."); + LOGV("extractAlbumArt"); + if (mRetriever == 0) { + LOGE("retriever is not initialized"); + return NULL; } - fclose(in); + return mRetriever->extractAlbumArt(); } -status_t MediaAlbumArt::setData(unsigned int len, const char* buf) { - clearData(); - length = len; - data = copyData(len, buf); - return (data != NULL)? OK: UNKNOWN_ERROR; +void MediaMetadataRetriever::DeathNotifier::binderDied(const wp& who) { + Mutex::Autolock lock(MediaMetadataRetriever::sServiceLock); + MediaMetadataRetriever::sService.clear(); + LOGW("MediaMetadataRetriever server died!"); } -char* MediaAlbumArt::copyData(unsigned int len, const char* buf) { - if (len == 0 || !buf) { - if (len == 0) { - LOGE("copyData: Length is 0."); - } else if (!buf) { - LOGE("copyData: buf is NULL pointer"); - } - return NULL; - } - char* copy = new char[len]; - if (!copy) { - LOGE("copyData: No enough memory to copy out the data."); - return NULL; +MediaMetadataRetriever::DeathNotifier::~DeathNotifier() +{ + Mutex::Autolock lock(sServiceLock); + if (sService != 0) { + sService->asBinder()->unlinkToDeath(this); } - memcpy(copy, buf, len); - return copy; } }; // namespace android -- cgit v1.1