mediametadataretriever.cpp revision 1b86fe063badb5f28c467ade39be0f4008688947
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 217562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IServiceManager.h> 227562408b2261d38415453378b6188f74fda99d88Mathias Agopian#include <binder/IPCThreadState.h> 2389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/mediametadataretriever.h> 241b86fe063badb5f28c467ade39be0f4008688947Andreas Huber#include <media/IMediaHTTPService.h> 2589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <media/IMediaPlayerService.h> 2689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <utils/Log.h> 2789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project#include <dlfcn.h> 2889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 2989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectnamespace android { 3089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project// client singleton for binder interface to service 3289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMutex MediaMetadataRetriever::sServiceLock; 3389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMediaPlayerService> MediaMetadataRetriever::sService; 3489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<MediaMetadataRetriever::DeathNotifier> MediaMetadataRetriever::sDeathNotifier; 3589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 3689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst sp<IMediaPlayerService>& MediaMetadataRetriever::getService() 3789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 3889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(sServiceLock); 397fc9a6fdf146ded90b51c52f4a05d797294dcb85Glenn Kasten if (sService == 0) { 4089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IServiceManager> sm = defaultServiceManager(); 4189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IBinder> binder; 4289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project do { 4389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project binder = sm->getService(String16("media.player")); 4489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (binder != 0) { 4589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project break; 4689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 475ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("MediaPlayerService not published, waiting..."); 4889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project usleep(500000); // 0.5 s 49e53b9ead781c36e96d6b6f012ddffc93a3d80f0dGlenn Kasten } while (true); 5089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sDeathNotifier == NULL) { 5189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sDeathNotifier = new DeathNotifier(); 5289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 5389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project binder->linkToDeath(sDeathNotifier); 5489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sService = interface_cast<IMediaPlayerService>(binder); 5589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 5629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE_IF(sService == 0, "no MediaPlayerService!?"); 5789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return sService; 5889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 5989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 6089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::MediaMetadataRetriever() 6189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 623856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("constructor"); 6389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project const sp<IMediaPlayerService>& service(getService()); 6489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (service == 0) { 6529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to obtain MediaMetadataRetrieverService"); 6689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return; 6789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 688d6cc842e8d525405c68e57fdf3bc5da0b4d7e87Glenn Kasten sp<IMediaMetadataRetriever> retriever(service->createMetadataRetriever()); 6989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (retriever == 0) { 7029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("failed to create IMediaMetadataRetriever object from server"); 7189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 7289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRetriever = retriever; 7389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 7489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 7589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::~MediaMetadataRetriever() 7689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 773856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("destructor"); 7889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project disconnect(); 7989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project IPCThreadState::self()->flushCommands(); 8089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 8189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 8289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectvoid MediaMetadataRetriever::disconnect() 8389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 843856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("disconnect"); 8589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sp<IMediaMetadataRetriever> retriever; 8689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project { 8789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock _l(mLock); 8889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project retriever = mRetriever; 8989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project mRetriever.clear(); 9089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (retriever != 0) { 9289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project retriever->disconnect(); 9389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 9489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 9589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 96af8791e112c8072452bd14ef3c43a47511d19542Andreas Huberstatus_t MediaMetadataRetriever::setDataSource( 971b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const sp<IMediaHTTPService> &httpService, 981b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const char *srcUrl, 991b86fe063badb5f28c467ade39be0f4008688947Andreas Huber const KeyedVector<String8, String8> *headers) 10089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1013856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setDataSource"); 102a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 10389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 10429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 10589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 10689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 10789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (srcUrl == NULL) { 10829357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("data source is a null pointer"); 10989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return UNKNOWN_ERROR; 11089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 1113856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("data source (%s)", srcUrl); 1121b86fe063badb5f28c467ade39be0f4008688947Andreas Huber return mRetriever->setDataSource(httpService, srcUrl, headers); 11389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 11489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 11589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectstatus_t MediaMetadataRetriever::setDataSource(int fd, int64_t offset, int64_t length) 11689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1173856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("setDataSource(%d, %lld, %lld)", fd, offset, length); 118a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 11989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 12029357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 12189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return INVALID_OPERATION; 12289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (fd < 0 || offset < 0 || length < 0) { 12429357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("Invalid negative argument"); 12589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return UNKNOWN_ERROR; 12689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 12789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->setDataSource(fd, offset, length); 12889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 12989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 13016afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dongsp<IMemory> MediaMetadataRetriever::getFrameAtTime(int64_t timeUs, int option) 13189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1323856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("getFrameAtTime: time(%lld us) option(%d)", timeUs, option); 133a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 13489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 13529357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 13689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 13789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 13816afe2fb439cab6125bb46a07a8078d4ce1c1ea5James Dong return mRetriever->getFrameAtTime(timeUs, option); 13989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 14089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 14189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectconst char* MediaMetadataRetriever::extractMetadata(int keyCode) 14289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1433856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("extractMetadata(%d)", keyCode); 144a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 14589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 14629357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 14789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 14889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 14989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->extractMetadata(keyCode); 15089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 15189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 15289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Projectsp<IMemory> MediaMetadataRetriever::extractAlbumArt() 15389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 1543856b090cd04ba5dd4a59a12430ed724d5995909Steve Block ALOGV("extractAlbumArt"); 155a17a1347ffe281fc70633ba8dc98f6cf49ac06ffDave Sparks Mutex::Autolock _l(mLock); 15689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (mRetriever == 0) { 15729357bc2c0dd7c43ad3bd0c8e3efa4e6fd9bfd47Steve Block ALOGE("retriever is not initialized"); 15889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return NULL; 15989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 16089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project return mRetriever->extractAlbumArt(); 16189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 16289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 1637c7be1e05634d96d08210efb4bdeb012ffba440dGlenn Kastenvoid MediaMetadataRetriever::DeathNotifier::binderDied(const wp<IBinder>& who __unused) { 16489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(MediaMetadataRetriever::sServiceLock); 16589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project MediaMetadataRetriever::sService.clear(); 1665ff1dd576bb93c45b44088a51544a18fc43ebf58Steve Block ALOGW("MediaMetadataRetriever server died!"); 16789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 16889fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 16989fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source ProjectMediaMetadataRetriever::DeathNotifier::~DeathNotifier() 17089fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project{ 17189fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project Mutex::Autolock lock(sServiceLock); 17289fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project if (sService != 0) { 17389fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project sService->asBinder()->unlinkToDeath(this); 17489fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project } 17589fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project} 17689fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project 17789fa4ad53f2f4d57adbc97ae1149fc00c9b6f3c5The Android Open Source Project}; // namespace android 178