19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Copyright 2008, The Android Open Source Project 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** you may not use this file except in compliance with the License. 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** You may obtain a copy of the License at 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** See the License for the specific language governing permissions and 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project** limitations under the License. 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project*/ 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project//#define LOG_NDEBUG 0 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "MediaMetadataRetriever" 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 210795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IServiceManager.h> 220795272aa226f4e965968a03daddc53ce30b7cdaMathias Agopian#include <binder/IPCThreadState.h> 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/mediametadataretriever.h> 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <media/IMediaPlayerService.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <utils/Log.h> 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <dlfcn.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectnamespace android { 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// client singleton for binder interface to service 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMutex MediaMetadataRetriever::sServiceLock; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IMediaPlayerService> MediaMetadataRetriever::sService; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst sp<IMediaPlayerService>& MediaMetadataRetriever::getService() 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(sServiceLock); 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sService.get() == 0) { 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IServiceManager> sm = defaultServiceManager(); 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IBinder> binder; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder = sm->getService(String16("media.player")); 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (binder != 0) { 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project break; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGW("MediaPlayerService not published, waiting..."); 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project usleep(500000); // 0.5 s 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } while(true); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sDeathNotifier == NULL) { 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sDeathNotifier = new DeathNotifier(); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder->linkToDeath(sDeathNotifier); 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sService = interface_cast<IMediaPlayerService>(binder); 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE_IF(sService == 0, "no MediaPlayerService!?"); 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return sService; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMediaMetadataRetriever::MediaMetadataRetriever() 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("constructor"); 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const sp<IMediaPlayerService>& service(getService()); 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (service == 0) { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("failed to obtain MediaMetadataRetrieverService"); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMediaMetadataRetriever> retriever(service->createMetadataRetriever(getpid())); 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever == 0) { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("failed to create IMediaMetadataRetriever object from server"); 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRetriever = retriever; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMediaMetadataRetriever::~MediaMetadataRetriever() 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("destructor"); 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project disconnect(); 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IPCThreadState::self()->flushCommands(); 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid MediaMetadataRetriever::disconnect() 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("disconnect"); 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sp<IMediaMetadataRetriever> retriever; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock _l(mLock); 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retriever = mRetriever; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mRetriever.clear(); 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (retriever != 0) { 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project retriever->disconnect(); 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 955b7ced6a4ebcec34a36d0779773bc9e671732dbfAndreas Huberstatus_t MediaMetadataRetriever::setDataSource( 965b7ced6a4ebcec34a36d0779773bc9e671732dbfAndreas Huber const char *srcUrl, const KeyedVector<String8, String8> *headers) 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("setDataSource"); 99db6cc0ba71a873ad0258e850cb939639b7857c26Dave Sparks Mutex::Autolock _l(mLock); 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRetriever == 0) { 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("retriever is not initialized"); 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_OPERATION; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (srcUrl == NULL) { 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("data source is a null pointer"); 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("data source (%s)", srcUrl); 1095b7ced6a4ebcec34a36d0779773bc9e671732dbfAndreas Huber return mRetriever->setDataSource(srcUrl, headers); 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 115db6cc0ba71a873ad0258e850cb939639b7857c26Dave Sparks Mutex::Autolock _l(mLock); 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRetriever == 0) { 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("retriever is not initialized"); 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_OPERATION; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fd < 0 || offset < 0 || length < 0) { 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("Invalid negative argument"); 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRetriever->setDataSource(fd, offset, length); 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dongsp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option) 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 129faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong LOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option); 130db6cc0ba71a873ad0258e850cb939639b7857c26Dave Sparks Mutex::Autolock _l(mLock); 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRetriever == 0) { 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("retriever is not initialized"); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 135faf09ba9405ff019b5ca7e2317debe4ff269d4f8James Dong return mRetriever->getFrameAtTime(timeUs, option); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectconst char* MediaMetadataRetriever::extractMetadata(int keyCode) 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("extractMetadata(%d)", keyCode); 141db6cc0ba71a873ad0258e850cb939639b7857c26Dave Sparks Mutex::Autolock _l(mLock); 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRetriever == 0) { 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("retriever is not initialized"); 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRetriever->extractMetadata(keyCode); 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectsp<IMemory> MediaMetadataRetriever::extractAlbumArt() 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGV("extractAlbumArt"); 152db6cc0ba71a873ad0258e850cb939639b7857c26Dave Sparks Mutex::Autolock _l(mLock); 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mRetriever == 0) { 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGE("retriever is not initialized"); 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NULL; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mRetriever->extractAlbumArt(); 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid MediaMetadataRetriever::DeathNotifier::binderDied(const wp<IBinder>& who) { 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(MediaMetadataRetriever::sServiceLock); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project MediaMetadataRetriever::sService.clear(); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project LOGW("MediaMetadataRetriever server died!"); 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source ProjectMediaMetadataRetriever::DeathNotifier::~DeathNotifier() 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Mutex::Autolock lock(sServiceLock); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (sService != 0) { 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project sService->asBinder()->unlinkToDeath(this); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project}; // namespace android 175