summaryrefslogtreecommitdiffstats
path: root/media/libmedia/mediametadataretriever.cpp
diff options
context:
space:
mode:
authorThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
committerThe Android Open Source Project <initial-contribution@android.com>2008-12-17 18:05:43 -0800
commit7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8 (patch)
treed9838a098f868ee2fcffc20627a8c9a33cb23377 /media/libmedia/mediametadataretriever.cpp
parent2729ea9262ca60d93047e984739887cfc89e82eb (diff)
downloadframeworks_av-7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8.zip
frameworks_av-7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8.tar.gz
frameworks_av-7b5eb023f8d87cca6d830ae6c11c6aadbe02aca8.tar.bz2
Code drop from //branches/cupcake/...@124589
Diffstat (limited to 'media/libmedia/mediametadataretriever.cpp')
-rw-r--r--media/libmedia/mediametadataretriever.cpp228
1 files changed, 117 insertions, 111 deletions
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 <media/mediametadataretriever.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
+//#define LOG_NDEBUG 0
#define LOG_TAG "MediaMetadataRetriever"
-#endif
+#include <utils/IServiceManager.h>
+#include <utils/IPCThreadState.h>
+#include <media/mediametadataretriever.h>
+#include <media/IMediaPlayerService.h>
#include <utils/Log.h>
#include <dlfcn.h>
namespace android {
-// Factory class function in shared libpvplayer.so
-typedef MediaMetadataRetrieverImpl* (*createRetriever_f)();
+// client singleton for binder interface to service
+Mutex MediaMetadataRetriever::sServiceLock;
+sp<IMediaPlayerService> MediaMetadataRetriever::sService;
+sp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier;
-MediaMetadataRetrieverImpl *MediaMetadataRetriever::mRetriever = NULL;
-void *MediaMetadataRetriever::mLibHandler = NULL;
-
-void MediaMetadataRetriever::create()
+const sp<IMediaPlayerService>& 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<IServiceManager> sm = defaultServiceManager();
+ sp<IBinder> 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<IMediaPlayerService>(binder);
}
-
- // Each time create a new MediaMetadataRetrieverImpl object.
- if (mRetriever) {
- delete mRetriever;
- }
- createRetriever_f createRetriever = reinterpret_cast<createRetriever_f>(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<IMediaPlayerService>& service(getService());
+ if (service == 0) {
+ LOGE("failed to obtain MediaMetadataRetrieverService");
return;
}
- mRetriever = createRetriever();
- if (!mRetriever) {
- LOGE("setDataSource: createRetriever failed in libpvplayer.so");
+ sp<IMediaMetadataRetriever> 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<IMediaMetadataRetriever> 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<IMemory> 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<IMemory> 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<IBinder>& 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