mediametadataretriever.cpp revision 2729ea9262ca60d93047e984739887cfc89e82eb
1/* 2** 3** Copyright 2008, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18#include <media/mediametadataretriever.h> 19 20#ifdef LOG_TAG 21#undef LOG_TAG 22#define LOG_TAG "MediaMetadataRetriever" 23#endif 24 25#include <utils/Log.h> 26#include <dlfcn.h> 27 28namespace android { 29 30// Factory class function in shared libpvplayer.so 31typedef MediaMetadataRetrieverImpl* (*createRetriever_f)(); 32 33MediaMetadataRetrieverImpl *MediaMetadataRetriever::mRetriever = NULL; 34void *MediaMetadataRetriever::mLibHandler = NULL; 35 36void MediaMetadataRetriever::create() 37{ 38 // Load libpvplayer library once and only once. 39 if (!mLibHandler) { 40 mLibHandler = dlopen("libopencoreplayer.so", RTLD_NOW); 41 if (!mLibHandler) { 42 LOGE("setDataSource: dlopen failed on libopencoreplayer.so"); 43 return; 44 } 45 } 46 47 // Each time create a new MediaMetadataRetrieverImpl object. 48 if (mRetriever) { 49 delete mRetriever; 50 } 51 createRetriever_f createRetriever = reinterpret_cast<createRetriever_f>(dlsym(mLibHandler, "createRetriever")); 52 if (!createRetriever) { 53 LOGE("setDataSource: dlsym failed on createRetriever in libpvplayer.so"); 54 return; 55 } 56 mRetriever = createRetriever(); 57 if (!mRetriever) { 58 LOGE("setDataSource: createRetriever failed in libpvplayer.so"); 59 } 60} 61 62status_t MediaMetadataRetriever::setDataSource(const char* srcUrl) 63{ 64 if (srcUrl == NULL) { 65 return UNKNOWN_ERROR; 66 } 67 68 if (mRetriever) { 69 return mRetriever->setDataSource(srcUrl); 70 } 71 return UNKNOWN_ERROR; 72} 73 74const char* MediaMetadataRetriever::extractMetadata(int keyCode) 75{ 76 if (mRetriever) { 77 return mRetriever->extractMetadata(keyCode); 78 } 79 return NULL; 80} 81 82MediaAlbumArt* MediaMetadataRetriever::extractAlbumArt() 83{ 84 if (mRetriever) { 85 return mRetriever->extractAlbumArt(); 86 } 87 return NULL; 88} 89 90SkBitmap* MediaMetadataRetriever::captureFrame() 91{ 92 if (mRetriever) { 93 return mRetriever->captureFrame(); 94 } 95 return NULL; 96} 97 98void MediaMetadataRetriever::setMode(int mode) 99{ 100 if (mRetriever) { 101 mRetriever->setMode(mode); 102 } 103} 104 105void MediaMetadataRetriever::release() 106{ 107 if (!mLibHandler) { 108 dlclose(mLibHandler); 109 mLibHandler = NULL; 110 } 111 if (!mRetriever) { 112 delete mRetriever; 113 mRetriever = NULL; 114 } 115} 116 117void MediaAlbumArt::clearData() { 118 if (data != NULL) { 119 delete []data; 120 data = NULL; 121 } 122 length = 0; 123} 124 125 126MediaAlbumArt::MediaAlbumArt(const char* url) 127{ 128 length = 0; 129 data = NULL; 130 FILE *in = fopen(url, "r"); 131 if (!in) { 132 LOGE("extractExternalAlbumArt: Failed to open external album art url: %s.", url); 133 return; 134 } 135 fseek(in, 0, SEEK_END); 136 length = ftell(in); // Allocating buffer of size equals to the external file size. 137 if (length == 0 || (data = new char[length]) == NULL) { 138 if (length == 0) { 139 LOGE("extractExternalAlbumArt: External album art url: %s has a size of 0.", url); 140 } else if (data == NULL) { 141 LOGE("extractExternalAlbumArt: No enough memory for storing the retrieved album art."); 142 length = 0; 143 } 144 fclose(in); 145 return; 146 } 147 rewind(in); 148 if (fread(data, 1, length, in) != length) { // Read failed. 149 length = 0; 150 delete []data; 151 data = NULL; 152 LOGE("extractExternalAlbumArt: Failed to retrieve the contents of an external album art."); 153 } 154 fclose(in); 155} 156 157status_t MediaAlbumArt::setData(unsigned int len, const char* buf) { 158 clearData(); 159 length = len; 160 data = copyData(len, buf); 161 return (data != NULL)? OK: UNKNOWN_ERROR; 162} 163 164char* MediaAlbumArt::copyData(unsigned int len, const char* buf) { 165 if (len == 0 || !buf) { 166 if (len == 0) { 167 LOGE("copyData: Length is 0."); 168 } else if (!buf) { 169 LOGE("copyData: buf is NULL pointer"); 170 } 171 return NULL; 172 } 173 char* copy = new char[len]; 174 if (!copy) { 175 LOGE("copyData: No enough memory to copy out the data."); 176 return NULL; 177 } 178 memcpy(copy, buf, len); 179 return copy; 180} 181 182}; // namespace android 183