MediaPlayerFactory.cpp revision f5bdd770d509373cc4174a55d0b81b223ecc4d81
16047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar/* 26047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** 36047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** Copyright 2012, The Android Open Source Project 46047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** 56047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** Licensed under the Apache License, Version 2.0 (the "License"); 66047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** you may not use this file except in compliance with the License. 76047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** You may obtain a copy of the License at 86047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** 96047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** http://www.apache.org/licenses/LICENSE-2.0 106047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** 116047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** Unless required by applicable law or agreed to in writing, software 126047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** distributed under the License is distributed on an "AS IS" BASIS, 136047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 146047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** See the License for the specific language governing permissions and 156047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar** limitations under the License. 166047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar*/ 176047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 186047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#define LOG_TAG "MediaPlayerFactory" 196047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <utils/Log.h> 206047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 216047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <cutils/properties.h> 226047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <media/IMediaPlayer.h> 236047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <media/stagefright/foundation/ADebug.h> 246047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <utils/Errors.h> 256047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include <utils/misc.h> 266047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 276047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include "MediaPlayerFactory.h" 286047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 296047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include "MidiFile.h" 306047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include "TestPlayerStub.h" 316047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include "StagefrightPlayer.h" 326047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar#include "nuplayer/NuPlayerDriver.h" 336047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 346047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarnamespace android { 356047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 366047998943beebd81e0ae1068df39c0cbee38628Yigit BoyarMutex MediaPlayerFactory::sLock; 376047998943beebd81e0ae1068df39c0cbee38628Yigit BoyarMediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap; 386047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarbool MediaPlayerFactory::sInitComplete = false; 396047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 406047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarstatus_t MediaPlayerFactory::registerFactory_l(IFactory* factory, 416047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar player_type type) { 426047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (NULL == factory) { 436047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar ALOGE("Failed to register MediaPlayerFactory of type %d, factory is" 446047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar " NULL.", type); 456047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return BAD_VALUE; 466047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 476047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 486047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (sFactoryMap.indexOfKey(type) >= 0) { 496047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar ALOGE("Failed to register MediaPlayerFactory of type %d, type is" 506047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar " already registered.", type); 516047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return ALREADY_EXISTS; 526047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 536047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 546047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (sFactoryMap.add(type, factory) < 0) { 556047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add" 566047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar " to map.", type); 576047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return UNKNOWN_ERROR; 586047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 596047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 606047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return OK; 616047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 626047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 636047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarplayer_type MediaPlayerFactory::getDefaultPlayerType() { 646047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar char value[PROPERTY_VALUE_MAX]; 656047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar if (property_get("media.stagefright.use-awesome", value, NULL) 666047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar && (!strcmp("1", value) || !strcasecmp("true", value))) { 676047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return STAGEFRIGHT_PLAYER; 686047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 696047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 706047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar // TODO: remove this EXPERIMENTAL developer settings property 71bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount if (property_get("persist.sys.media.use-awesome", value, NULL) 726047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar && !strcasecmp("true", value)) { 736047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return STAGEFRIGHT_PLAYER; 746047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar } 756047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 766047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return NU_PLAYER; 776047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 786047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 796047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarstatus_t MediaPlayerFactory::registerFactory(IFactory* factory, 806047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar player_type type) { 816047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Mutex::Autolock lock_(&sLock); 826047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar return registerFactory_l(factory, type); 836047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar} 846047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar 856047998943beebd81e0ae1068df39c0cbee38628Yigit Boyarvoid MediaPlayerFactory::unregisterFactory(player_type type) { 866047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar Mutex::Autolock lock_(&sLock); 876047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar sFactoryMap.removeItem(type); 88bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount} 89bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount 90bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount#define GET_PLAYER_TYPE_IMPL(a...) \ 91bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount Mutex::Autolock lock_(&sLock); \ 92bb4a033fcd5cd20e5be46ef8ead442dc7db2454dGeorge Mount \ 936047998943beebd81e0ae1068df39c0cbee38628Yigit Boyar player_type ret = STAGEFRIGHT_PLAYER; \ 94 float bestScore = 0.0; \ 95 \ 96 for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ 97 \ 98 IFactory* v = sFactoryMap.valueAt(i); \ 99 float thisScore; \ 100 CHECK(v != NULL); \ 101 thisScore = v->scoreFactory(a, bestScore); \ 102 if (thisScore > bestScore) { \ 103 ret = sFactoryMap.keyAt(i); \ 104 bestScore = thisScore; \ 105 } \ 106 } \ 107 \ 108 if (0.0 == bestScore) { \ 109 ret = getDefaultPlayerType(); \ 110 } \ 111 \ 112 return ret; 113 114player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 115 const char* url) { 116 GET_PLAYER_TYPE_IMPL(client, url); 117} 118 119player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 120 int fd, 121 int64_t offset, 122 int64_t length) { 123 GET_PLAYER_TYPE_IMPL(client, fd, offset, length); 124} 125 126player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 127 const sp<IStreamSource> &source) { 128 GET_PLAYER_TYPE_IMPL(client, source); 129} 130 131#undef GET_PLAYER_TYPE_IMPL 132 133sp<MediaPlayerBase> MediaPlayerFactory::createPlayer( 134 player_type playerType, 135 void* cookie, 136 notify_callback_f notifyFunc) { 137 sp<MediaPlayerBase> p; 138 IFactory* factory; 139 status_t init_result; 140 Mutex::Autolock lock_(&sLock); 141 142 if (sFactoryMap.indexOfKey(playerType) < 0) { 143 ALOGE("Failed to create player object of type %d, no registered" 144 " factory", playerType); 145 return p; 146 } 147 148 factory = sFactoryMap.valueFor(playerType); 149 CHECK(NULL != factory); 150 p = factory->createPlayer(); 151 152 if (p == NULL) { 153 ALOGE("Failed to create player object of type %d, create failed", 154 playerType); 155 return p; 156 } 157 158 init_result = p->initCheck(); 159 if (init_result == NO_ERROR) { 160 p->setNotifyCallback(cookie, notifyFunc); 161 } else { 162 ALOGE("Failed to create player object of type %d, initCheck failed" 163 " (res = %d)", playerType, init_result); 164 p.clear(); 165 } 166 167 return p; 168} 169 170/***************************************************************************** 171 * * 172 * Built-In Factory Implementations * 173 * * 174 *****************************************************************************/ 175 176class StagefrightPlayerFactory : 177 public MediaPlayerFactory::IFactory { 178 public: 179 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 180 int fd, 181 int64_t offset, 182 int64_t /*length*/, 183 float /*curScore*/) { 184 char buf[20]; 185 lseek(fd, offset, SEEK_SET); 186 read(fd, buf, sizeof(buf)); 187 lseek(fd, offset, SEEK_SET); 188 189 uint32_t ident = *((uint32_t*)buf); 190 191 // Ogg vorbis? 192 if (ident == 0x5367674f) // 'OggS' 193 return 1.0; 194 195 return 0.0; 196 } 197 198 virtual sp<MediaPlayerBase> createPlayer() { 199 ALOGV(" create StagefrightPlayer"); 200 return new StagefrightPlayer(); 201 } 202}; 203 204class NuPlayerFactory : public MediaPlayerFactory::IFactory { 205 public: 206 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 207 const char* url, 208 float curScore) { 209 static const float kOurScore = 0.8; 210 211 if (kOurScore <= curScore) 212 return 0.0; 213 214 if (!strncasecmp("http://", url, 7) 215 || !strncasecmp("https://", url, 8) 216 || !strncasecmp("file://", url, 7)) { 217 size_t len = strlen(url); 218 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 219 return kOurScore; 220 } 221 222 if (strstr(url,"m3u8")) { 223 return kOurScore; 224 } 225 226 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) { 227 return kOurScore; 228 } 229 } 230 231 if (!strncasecmp("rtsp://", url, 7)) { 232 return kOurScore; 233 } 234 235 return 0.0; 236 } 237 238 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 239 const sp<IStreamSource>& /*source*/, 240 float /*curScore*/) { 241 return 1.0; 242 } 243 244 virtual sp<MediaPlayerBase> createPlayer() { 245 ALOGV(" create NuPlayer"); 246 return new NuPlayerDriver; 247 } 248}; 249 250class SonivoxPlayerFactory : public MediaPlayerFactory::IFactory { 251 public: 252 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 253 const char* url, 254 float curScore) { 255 static const float kOurScore = 0.4; 256 static const char* const FILE_EXTS[] = { ".mid", 257 ".midi", 258 ".smf", 259 ".xmf", 260 ".mxmf", 261 ".imy", 262 ".rtttl", 263 ".rtx", 264 ".ota" }; 265 if (kOurScore <= curScore) 266 return 0.0; 267 268 // use MidiFile for MIDI extensions 269 int lenURL = strlen(url); 270 for (int i = 0; i < NELEM(FILE_EXTS); ++i) { 271 int len = strlen(FILE_EXTS[i]); 272 int start = lenURL - len; 273 if (start > 0) { 274 if (!strncasecmp(url + start, FILE_EXTS[i], len)) { 275 return kOurScore; 276 } 277 } 278 } 279 280 return 0.0; 281 } 282 283 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 284 int fd, 285 int64_t offset, 286 int64_t length, 287 float curScore) { 288 static const float kOurScore = 0.8; 289 290 if (kOurScore <= curScore) 291 return 0.0; 292 293 // Some kind of MIDI? 294 EAS_DATA_HANDLE easdata; 295 if (EAS_Init(&easdata) == EAS_SUCCESS) { 296 EAS_FILE locator; 297 locator.path = NULL; 298 locator.fd = fd; 299 locator.offset = offset; 300 locator.length = length; 301 EAS_HANDLE eashandle; 302 if (EAS_OpenFile(easdata, &locator, &eashandle) == EAS_SUCCESS) { 303 EAS_CloseFile(easdata, eashandle); 304 EAS_Shutdown(easdata); 305 return kOurScore; 306 } 307 EAS_Shutdown(easdata); 308 } 309 310 return 0.0; 311 } 312 313 virtual sp<MediaPlayerBase> createPlayer() { 314 ALOGV(" create MidiFile"); 315 return new MidiFile(); 316 } 317}; 318 319class TestPlayerFactory : public MediaPlayerFactory::IFactory { 320 public: 321 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 322 const char* url, 323 float /*curScore*/) { 324 if (TestPlayerStub::canBeUsed(url)) { 325 return 1.0; 326 } 327 328 return 0.0; 329 } 330 331 virtual sp<MediaPlayerBase> createPlayer() { 332 ALOGV("Create Test Player stub"); 333 return new TestPlayerStub(); 334 } 335}; 336 337void MediaPlayerFactory::registerBuiltinFactories() { 338 Mutex::Autolock lock_(&sLock); 339 340 if (sInitComplete) 341 return; 342 343 registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER); 344 registerFactory_l(new NuPlayerFactory(), NU_PLAYER); 345 registerFactory_l(new SonivoxPlayerFactory(), SONIVOX_PLAYER); 346 registerFactory_l(new TestPlayerFactory(), TEST_PLAYER); 347 348 sInitComplete = true; 349} 350 351} // namespace android 352