183 lines
4.6 KiB
C++
183 lines
4.6 KiB
C++
/*
|
|
**
|
|
** 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
|