167e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber/* 267e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * Copyright (C) 2009 The Android Open Source Project 367e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * 467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * Licensed under the Apache License, Version 2.0 (the "License"); 567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * you may not use this file except in compliance with the License. 667e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * You may obtain a copy of the License at 767e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * 867e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * http://www.apache.org/licenses/LICENSE-2.0 967e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * 1067e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * Unless required by applicable law or agreed to in writing, software 1167e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * distributed under the License is distributed on an "AS IS" BASIS, 1267e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1367e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * See the License for the specific language governing permissions and 1467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber * limitations under the License. 1567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber */ 1667e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 17fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber//#define LOG_NDEBUG 0 18fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#define LOG_TAG "StagefrightMediaScanner" 19fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <utils/Log.h> 20fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 21a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen#include <sys/types.h> 22a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen#include <sys/stat.h> 23a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen#include <fcntl.h> 24a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen 2567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber#include <media/stagefright/StagefrightMediaScanner.h> 2667e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 271b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 282e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber#include <media/mediametadataretriever.h> 292e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber#include <private/media/VideoFrame.h> 3067e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 31fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber// Sonivox includes 32fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber#include <libsonivox/eas.h> 33fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 3467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Hubernamespace android { 3567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 360a095d09464ba18e288a3f529410af0f1257ac2aMike LockwoodStagefrightMediaScanner::StagefrightMediaScanner() {} 3767e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 3867e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas HuberStagefrightMediaScanner::~StagefrightMediaScanner() {} 3967e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 40fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huberstatic bool FileHasAcceptableExtension(const char *extension) { 41fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const char *kValidExtensions[] = { 42fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ".mp3", ".mp4", ".m4a", ".3gp", ".3gpp", ".3g2", ".3gpp2", 43fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber ".mpeg", ".ogg", ".mid", ".smf", ".imy", ".wma", ".aac", 44093437c388e5dff6903a3d43f2ca9f8a1ba4744aAndreas Huber ".wav", ".amr", ".midi", ".xmf", ".rtttl", ".rtx", ".ota", 458d30cc86d36c5e2d7d8defab8f58faed4139ed7fAndreas Huber ".mkv", ".mka", ".webm", ".ts", ".fl", ".flac", ".mxmf", 46b7047796795083484c0bc9003f346b4022c3be9aMarco Nelissen ".avi", ".mpeg", ".mpg", ".awb", ".mpga" 47fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber }; 48fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber static const size_t kNumValidExtensions = 49fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sizeof(kValidExtensions) / sizeof(kValidExtensions[0]); 50fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 51fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber for (size_t i = 0; i < kNumValidExtensions; ++i) { 52fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcasecmp(extension, kValidExtensions[i])) { 53fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return true; 54fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 55fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 56fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 57fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return false; 58fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 59fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 607188e55f54a43c55fd6b96454720c447f1dc454eJeff Brownstatic MediaScanResult HandleMIDI( 61fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const char *filename, MediaScannerClient *client) { 62fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // get the library configuration and do sanity check 63fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const S_EAS_LIB_CONFIG* pLibConfig = EAS_Config(); 64fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if ((pLibConfig == NULL) || (LIB_VERSION != pLibConfig->libVersion)) { 6529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("EAS library/header mismatch\n"); 667188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_ERROR; 67fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 68fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_I32 temp; 69fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 70fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber // spin up a new EAS engine 71fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_DATA_HANDLE easData = NULL; 72fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_HANDLE easHandle = NULL; 73fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_RESULT result = EAS_Init(&easData); 74fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (result == EAS_SUCCESS) { 75fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_FILE file; 76fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber file.path = filename; 77fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber file.fd = 0; 78fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber file.offset = 0; 79fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber file.length = 0; 80fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber result = EAS_OpenFile(easData, &file, &easHandle); 81fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 82fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (result == EAS_SUCCESS) { 83fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber result = EAS_Prepare(easData, easHandle); 84fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 85fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (result == EAS_SUCCESS) { 86fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber result = EAS_ParseMetaData(easData, easHandle, &temp); 87fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 88fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (easHandle) { 89fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_CloseFile(easData, easHandle); 90fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 91fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (easData) { 92fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber EAS_Shutdown(easData); 93fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 94fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 95fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (result != EAS_SUCCESS) { 967188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_SKIPPED; 97fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 98fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 99fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber char buffer[20]; 100fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber sprintf(buffer, "%ld", temp); 1017188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown status_t status = client->addStringTag("duration", buffer); 102153cefdf4acab25355f590d7760ebf73ef6096a9Marco Nelissen if (status != OK) { 1037188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_ERROR; 1047188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown } 1057188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_OK; 106fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber} 107fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 1087188e55f54a43c55fd6b96454720c447f1dc454eJeff BrownMediaScanResult StagefrightMediaScanner::processFile( 10967e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber const char *path, const char *mimeType, 11067e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber MediaScannerClient &client) { 1113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("processFile '%s'.", path); 1122e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber 11367e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber client.setLocale(locale()); 11467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber client.beginFile(); 1157188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown MediaScanResult result = processFileInternal(path, mimeType, client); 1167188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown client.endFile(); 1177188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return result; 1187188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown} 11967e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 1207188e55f54a43c55fd6b96454720c447f1dc454eJeff BrownMediaScanResult StagefrightMediaScanner::processFileInternal( 12184333e0475bc911adc16417f4ca327c975cf6c36Andreas Huber const char *path, const char * /* mimeType */, 1227188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown MediaScannerClient &client) { 123fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber const char *extension = strrchr(path, '.'); 124fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 125fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!extension) { 1267188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_SKIPPED; 127fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 128fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 129fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!FileHasAcceptableExtension(extension)) { 1307188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_SKIPPED; 131fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 132fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 133fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (!strcasecmp(extension, ".mid") 134fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".smf") 135fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".imy") 136fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".midi") 137fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".xmf") 138fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".rtttl") 139fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber || !strcasecmp(extension, ".rtx") 1408d30cc86d36c5e2d7d8defab8f58faed4139ed7fAndreas Huber || !strcasecmp(extension, ".ota") 1418d30cc86d36c5e2d7d8defab8f58faed4139ed7fAndreas Huber || !strcasecmp(extension, ".mxmf")) { 1427188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return HandleMIDI(path, &client); 1437188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown } 1447188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown 1457188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); 1467188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown 147a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen int fd = open(path, O_RDONLY | O_LARGEFILE); 148a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen status_t status; 149a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen if (fd < 0) { 150a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen // couldn't open it locally, maybe the media server can? 1511b86fe063badb5f28c467ade39be0f4008688947Andreas Huber status = mRetriever->setDataSource(NULL /* httpService */, path); 152a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen } else { 153a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen status = mRetriever->setDataSource(fd, 0, 0x7ffffffffffffffL); 154a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen close(fd); 155a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen } 156a28976b04c70cef3c8e79137478b6a7bc05608acMarco Nelissen 1577188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown if (status) { 1587188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_ERROR; 1597188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown } 1607188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown 1617188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown const char *value; 1627188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown if ((value = mRetriever->extractMetadata( 1637188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown METADATA_KEY_MIMETYPE)) != NULL) { 1647188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown status = client.setMimeType(value); 1657188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown if (status) { 1667188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_ERROR; 1676ed70d2d41f9929d1c3f5179d947766495f9efe5Hiroshi Takekawa } 1687188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown } 1690a095d09464ba18e288a3f529410af0f1257ac2aMike Lockwood 1707188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown struct KeyMap { 1717188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown const char *tag; 1727188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown int key; 1737188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown }; 1747188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown static const KeyMap kKeyMap[] = { 1757188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "tracknumber", METADATA_KEY_CD_TRACK_NUMBER }, 1767188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "discnumber", METADATA_KEY_DISC_NUMBER }, 1777188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "album", METADATA_KEY_ALBUM }, 1787188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "artist", METADATA_KEY_ARTIST }, 1797188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "albumartist", METADATA_KEY_ALBUMARTIST }, 1807188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "composer", METADATA_KEY_COMPOSER }, 1817188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "genre", METADATA_KEY_GENRE }, 1827188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "title", METADATA_KEY_TITLE }, 1837188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "year", METADATA_KEY_YEAR }, 1847188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "duration", METADATA_KEY_DURATION }, 1857188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "writer", METADATA_KEY_WRITER }, 1867188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "compilation", METADATA_KEY_COMPILATION }, 1877188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown { "isdrm", METADATA_KEY_IS_DRM }, 1884762a5164a986bd6a7ca0e7aba43881b64f146ddMarco Nelissen { "width", METADATA_KEY_VIDEO_WIDTH }, 1894762a5164a986bd6a7ca0e7aba43881b64f146ddMarco Nelissen { "height", METADATA_KEY_VIDEO_HEIGHT }, 1907188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown }; 1917188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown static const size_t kNumEntries = sizeof(kKeyMap) / sizeof(kKeyMap[0]); 1927188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown 1937188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown for (size_t i = 0; i < kNumEntries; ++i) { 1947188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown const char *value; 1957188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown if ((value = mRetriever->extractMetadata(kKeyMap[i].key)) != NULL) { 1967188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown status = client.addStringTag(kKeyMap[i].tag, value); 197153cefdf4acab25355f590d7760ebf73ef6096a9Marco Nelissen if (status != OK) { 1987188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_ERROR; 19967e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber } 20067e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber } 20167e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber } 20267e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 2037188e55f54a43c55fd6b96454720c447f1dc454eJeff Brown return MEDIA_SCAN_RESULT_OK; 20467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber} 20567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 206f3e80dddd7376aa9deeb27de25e1d50030a2ad98Elliott HughesMediaAlbumArt *StagefrightMediaScanner::extractAlbumArt(int fd) { 2073856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("extractAlbumArt %d", fd); 2082e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber 209c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong off64_t size = lseek64(fd, 0, SEEK_END); 210fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber if (size < 0) { 211fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber return NULL; 212fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 213c7fc37a3dab9bd1f96713649f351b5990e6316ffJames Dong lseek64(fd, 0, SEEK_SET); 214fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber 2150a095d09464ba18e288a3f529410af0f1257ac2aMike Lockwood sp<MediaMetadataRetriever> mRetriever(new MediaMetadataRetriever); 2167f7d52ac18dfc3c6d8f6267dad29306613e9bd0eJames Dong if (mRetriever->setDataSource(fd, 0, size) == OK) { 2172e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber sp<IMemory> mem = mRetriever->extractAlbumArt(); 2182e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber if (mem != NULL) { 2192e39c1ca101e01ff13b03129a87939e7982b25bfAndreas Huber MediaAlbumArt *art = static_cast<MediaAlbumArt *>(mem->pointer()); 220f3e80dddd7376aa9deeb27de25e1d50030a2ad98Elliott Hughes return art->clone(); 221fc9ba09e3bb368f823d473f5e2bb9aa32dba6289Andreas Huber } 22267e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber } 22367e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 22467e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber return NULL; 22567e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber} 22667e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber 22767e5a4f6f6879d512a859e5dba92e9beec7a2f91Andreas Huber} // namespace android 228