blob: 9cbafbc552f79d03364675e6bedcae6c6b755fa5 [file] [log] [blame]
/*
**
** Copyright 2008, The Android Open Source Project
**
** Licensed under the Apache License, Version 2.0 (the "License");
** you may not use this file except in compliance with the License.
** You may obtain a copy of the License at
**
** http://www.apache.org/licenses/LICENSE-2.0
**
** Unless required by applicable law or agreed to in writing, software
** distributed under the License is distributed on an "AS IS" BASIS,
** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
** See the License for the specific language governing permissions and
** limitations under the License.
*/
#include <media/mediametadataretriever.h>
#ifdef LOG_TAG
#undef LOG_TAG
#define LOG_TAG "MediaMetadataRetriever"
#endif
#include <utils/Log.h>
#include <dlfcn.h>
namespace android {
// Factory class function in shared libpvplayer.so
typedef MediaMetadataRetrieverImpl* (*createRetriever_f)();
MediaMetadataRetrieverImpl *MediaMetadataRetriever::mRetriever = NULL;
void *MediaMetadataRetriever::mLibHandler = NULL;
void MediaMetadataRetriever::create()
{
// 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;
}
}
// 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");
return;
}
mRetriever = createRetriever();
if (!mRetriever) {
LOGE("setDataSource: createRetriever failed in libpvplayer.so");
}
}
status_t MediaMetadataRetriever::setDataSource(const char* srcUrl)
{
if (srcUrl == NULL) {
return UNKNOWN_ERROR;
}
if (mRetriever) {
return mRetriever->setDataSource(srcUrl);
}
return UNKNOWN_ERROR;
}
const char* MediaMetadataRetriever::extractMetadata(int keyCode)
{
if (mRetriever) {
return mRetriever->extractMetadata(keyCode);
}
return NULL;
}
MediaAlbumArt* MediaMetadataRetriever::extractAlbumArt()
{
if (mRetriever) {
return mRetriever->extractAlbumArt();
}
return NULL;
}
SkBitmap* MediaMetadataRetriever::captureFrame()
{
if (mRetriever) {
return mRetriever->captureFrame();
}
return NULL;
}
void MediaMetadataRetriever::setMode(int mode)
{
if (mRetriever) {
mRetriever->setMode(mode);
}
}
void MediaMetadataRetriever::release()
{
if (!mLibHandler) {
dlclose(mLibHandler);
mLibHandler = NULL;
}
if (!mRetriever) {
delete mRetriever;
mRetriever = NULL;
}
}
void MediaAlbumArt::clearData() {
if (data != NULL) {
delete []data;
data = NULL;
}
length = 0;
}
MediaAlbumArt::MediaAlbumArt(const char* url)
{
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.");
}
fclose(in);
}
status_t MediaAlbumArt::setData(unsigned int len, const char* buf) {
clearData();
length = len;
data = copyData(len, buf);
return (data != NULL)? OK: UNKNOWN_ERROR;
}
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;
}
memcpy(copy, buf, len);
return copy;
}
}; // namespace android