189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project/* 289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Copyright 2008, The Android Open Source Project 489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Licensed under the Apache License, Version 2.0 (the "License"); 689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** you may not use this file except in compliance with the License. 789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** You may obtain a copy of the License at 889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** http://www.apache.org/licenses/LICENSE-2.0 1089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** 1189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** Unless required by applicable law or agreed to in writing, software 1289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** distributed under the License is distributed on an "AS IS" BASIS, 1389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** See the License for the specific language governing permissions and 1589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project** limitations under the License. 1689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project*/ 1789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project//#define LOG_NDEBUG 0 1989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#define LOG_TAG "MediaMetadataRetriever" 2089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2134fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn#include <inttypes.h> 2234fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn 237562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h> 247562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h> 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/mediametadataretriever.h> 261b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/IMediaPlayerService.h> 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h> 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <dlfcn.h> 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// client singleton for binder interface to service 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMutex MediaMetadataRetriever::sServiceLock; 3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMediaPlayerService> MediaMetadataRetriever::sService; 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier; 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst sp<IMediaPlayerService>& MediaMetadataRetriever::getService() 3989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(sServiceLock); 417fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten if (sService == 0) { 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IServiceManager> sm = defaultServiceManager(); 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IBinder> binder; 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project binder = sm->getService(String16("media.player")); 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (binder != 0) { 4789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 495ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("MediaPlayerService not published, waiting..."); 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project usleep(500000); // 0.5 s 51e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } while (true); 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sDeathNotifier == NULL) { 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sDeathNotifier = new DeathNotifier(); 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project binder->linkToDeath(sDeathNotifier); 5689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sService = interface_cast<IMediaPlayerService>(binder); 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 5829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE_IF(sService == 0, "no MediaPlayerService!?"); 5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return sService; 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::MediaMetadataRetriever() 6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 643856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("constructor"); 6589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const sp<IMediaPlayerService>& service(getService()); 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (service == 0) { 6729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to obtain MediaMetadataRetrieverService"); 6889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 708d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten sp<IMediaMetadataRetriever> retriever(service->createMetadataRetriever()); 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (retriever == 0) { 7229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to create IMediaMetadataRetriever object from server"); 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRetriever = retriever; 7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::~MediaMetadataRetriever() 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 793856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("destructor"); 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project disconnect(); 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaMetadataRetriever::disconnect() 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 863856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("disconnect"); 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IMediaMetadataRetriever> retriever; 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock _l(mLock); 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project retriever = mRetriever; 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRetriever.clear(); 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (retriever != 0) { 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project retriever->disconnect(); 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 9789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 98af8791e112c8072452bd14ef3c43a47511d19542Andreas Huberstatus_t MediaMetadataRetriever::setDataSource( 991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<IMediaHTTPService> &httpService, 1001b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const char *srcUrl, 1011b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const KeyedVector<String8, String8> *headers) 10289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1033856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setDataSource"); 104a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 10629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 10889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (srcUrl == NULL) { 11029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("data source is a null pointer"); 11189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return UNKNOWN_ERROR; 11289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 1133856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("data source (%s)", srcUrl); 1141b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mRetriever->setDataSource(httpService, srcUrl, headers); 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) 11889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 11934fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn ALOGV("setDataSource(%d, %" PRId64 ", %" PRId64 ")", fd, offset, length); 120a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 12229357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 12489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (fd < 0 || offset < 0 || length < 0) { 12629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid negative argument"); 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return UNKNOWN_ERROR; 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->setDataSource(fd, offset, length); 13089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13216afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dongsp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option) 13389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 13434fb29696b0f3abf61b10f8d053b1f33d501de0aMark Salyzyn ALOGV("getFrameAtTime: time(%" PRId64 " us) option(%d)", timeUs, option); 135a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 13729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 13889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14016afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong return mRetriever->getFrameAtTime(timeUs, option); 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst char* MediaMetadataRetriever::extractMetadata(int keyCode) 14489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1453856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("extractMetadata(%d)", keyCode); 146a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 14829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->extractMetadata(keyCode); 15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMemory> MediaMetadataRetriever::extractAlbumArt() 15589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1563856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("extractAlbumArt"); 157a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 15929357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->extractAlbumArt(); 16389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1657c7be1e05634d96d08210efb4bdeb012ffba440dGlenn Kastenvoid MediaMetadataRetriever::DeathNotifier::binderDied(const wp<IBinder>& who __unused) { 16689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(MediaMetadataRetriever::sServiceLock); 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project MediaMetadataRetriever::sService.clear(); 1685ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("MediaMetadataRetriever server died!"); 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::DeathNotifier::~DeathNotifier() 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(sServiceLock); 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sService != 0) { 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sService->asBinder()->unlinkToDeath(this); 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 17889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 180