MediaPlayerFactory.cpp revision 0e8928bf4f2b01b783f6da97d15e8f1abb0fd7d7
1/* 2** 3** Copyright 2012, The Android Open Source Project 4** 5** Licensed under the Apache License, Version 2.0 (the "License"); 6** you may not use this file except in compliance with the License. 7** You may obtain a copy of the License at 8** 9** http://www.apache.org/licenses/LICENSE-2.0 10** 11** Unless required by applicable law or agreed to in writing, software 12** distributed under the License is distributed on an "AS IS" BASIS, 13** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14** See the License for the specific language governing permissions and 15** limitations under the License. 16*/ 17 18//#define LOG_NDEBUG 0 19#define LOG_TAG "MediaPlayerFactory" 20#include <utils/Log.h> 21 22#include <cutils/properties.h> 23#include <media/IMediaPlayer.h> 24#include <media/stagefright/DataSource.h> 25#include <media/stagefright/FileSource.h> 26#include <media/stagefright/foundation/ADebug.h> 27#include <utils/Errors.h> 28#include <utils/misc.h> 29 30#include "MediaPlayerFactory.h" 31 32#include "TestPlayerStub.h" 33#include "StagefrightPlayer.h" 34#include "nuplayer/NuPlayerDriver.h" 35 36namespace android { 37 38Mutex MediaPlayerFactory::sLock; 39MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap; 40bool MediaPlayerFactory::sInitComplete = false; 41 42status_t MediaPlayerFactory::registerFactory_l(IFactory* factory, 43 player_type type) { 44 if (NULL == factory) { 45 ALOGE("Failed to register MediaPlayerFactory of type %d, factory is" 46 " NULL.", type); 47 return BAD_VALUE; 48 } 49 50 if (sFactoryMap.indexOfKey(type) >= 0) { 51 ALOGE("Failed to register MediaPlayerFactory of type %d, type is" 52 " already registered.", type); 53 return ALREADY_EXISTS; 54 } 55 56 if (sFactoryMap.add(type, factory) < 0) { 57 ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add" 58 " to map.", type); 59 return UNKNOWN_ERROR; 60 } 61 62 return OK; 63} 64 65static player_type getDefaultPlayerType() { 66 char value[PROPERTY_VALUE_MAX]; 67 if (property_get("media.stagefright.use-awesome", value, NULL) 68 && (!strcmp("1", value) || !strcasecmp("true", value))) { 69 return STAGEFRIGHT_PLAYER; 70 } 71 72 // TODO: remove this EXPERIMENTAL developer settings property 73 if (property_get("persist.sys.media.use-awesome", value, NULL) 74 && !strcasecmp("true", value)) { 75 return STAGEFRIGHT_PLAYER; 76 } 77 78 return NU_PLAYER; 79} 80 81status_t MediaPlayerFactory::registerFactory(IFactory* factory, 82 player_type type) { 83 Mutex::Autolock lock_(&sLock); 84 return registerFactory_l(factory, type); 85} 86 87void MediaPlayerFactory::unregisterFactory(player_type type) { 88 Mutex::Autolock lock_(&sLock); 89 sFactoryMap.removeItem(type); 90} 91 92#define GET_PLAYER_TYPE_IMPL(a...) \ 93 Mutex::Autolock lock_(&sLock); \ 94 \ 95 player_type ret = STAGEFRIGHT_PLAYER; \ 96 float bestScore = 0.0; \ 97 \ 98 for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ 99 \ 100 IFactory* v = sFactoryMap.valueAt(i); \ 101 float thisScore; \ 102 CHECK(v != NULL); \ 103 thisScore = v->scoreFactory(a, bestScore); \ 104 if (thisScore > bestScore) { \ 105 ret = sFactoryMap.keyAt(i); \ 106 bestScore = thisScore; \ 107 } \ 108 } \ 109 \ 110 if (0.0 == bestScore) { \ 111 ret = getDefaultPlayerType(); \ 112 } \ 113 \ 114 return ret; 115 116player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 117 const char* url) { 118 GET_PLAYER_TYPE_IMPL(client, url); 119} 120 121player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 122 int fd, 123 int64_t offset, 124 int64_t length) { 125 GET_PLAYER_TYPE_IMPL(client, fd, offset, length); 126} 127 128player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 129 const sp<IStreamSource> &source) { 130 GET_PLAYER_TYPE_IMPL(client, source); 131} 132 133#undef GET_PLAYER_TYPE_IMPL 134 135sp<MediaPlayerBase> MediaPlayerFactory::createPlayer( 136 player_type playerType, 137 void* cookie, 138 notify_callback_f notifyFunc) { 139 sp<MediaPlayerBase> p; 140 IFactory* factory; 141 status_t init_result; 142 Mutex::Autolock lock_(&sLock); 143 144 if (sFactoryMap.indexOfKey(playerType) < 0) { 145 ALOGE("Failed to create player object of type %d, no registered" 146 " factory", playerType); 147 return p; 148 } 149 150 factory = sFactoryMap.valueFor(playerType); 151 CHECK(NULL != factory); 152 p = factory->createPlayer(); 153 154 if (p == NULL) { 155 ALOGE("Failed to create player object of type %d, create failed", 156 playerType); 157 return p; 158 } 159 160 init_result = p->initCheck(); 161 if (init_result == NO_ERROR) { 162 p->setNotifyCallback(cookie, notifyFunc); 163 } else { 164 ALOGE("Failed to create player object of type %d, initCheck failed" 165 " (res = %d)", playerType, init_result); 166 p.clear(); 167 } 168 169 return p; 170} 171 172/***************************************************************************** 173 * * 174 * Built-In Factory Implementations * 175 * * 176 *****************************************************************************/ 177 178class StagefrightPlayerFactory : 179 public MediaPlayerFactory::IFactory { 180 public: 181 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 182 int fd, 183 int64_t offset, 184 int64_t /*length*/, 185 float /*curScore*/) { 186 if (getDefaultPlayerType() 187 == STAGEFRIGHT_PLAYER) { 188 char buf[20]; 189 lseek(fd, offset, SEEK_SET); 190 read(fd, buf, sizeof(buf)); 191 lseek(fd, offset, SEEK_SET); 192 193 uint32_t ident = *((uint32_t*)buf); 194 195 // Ogg vorbis? 196 if (ident == 0x5367674f) // 'OggS' 197 return 1.0; 198 } 199 200 return 0.0; 201 } 202 203 virtual sp<MediaPlayerBase> createPlayer() { 204 ALOGV(" create StagefrightPlayer"); 205 return new StagefrightPlayer(); 206 } 207}; 208 209class NuPlayerFactory : public MediaPlayerFactory::IFactory { 210 public: 211 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 212 const char* url, 213 float curScore) { 214 static const float kOurScore = 0.8; 215 216 if (kOurScore <= curScore) 217 return 0.0; 218 219 if (!strncasecmp("http://", url, 7) 220 || !strncasecmp("https://", url, 8) 221 || !strncasecmp("file://", url, 7)) { 222 size_t len = strlen(url); 223 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 224 return kOurScore; 225 } 226 227 if (strstr(url,"m3u8")) { 228 return kOurScore; 229 } 230 231 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) { 232 return kOurScore; 233 } 234 } 235 236 if (!strncasecmp("rtsp://", url, 7)) { 237 return kOurScore; 238 } 239 240 return 0.0; 241 } 242 243 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 244 const sp<IStreamSource>& /*source*/, 245 float /*curScore*/) { 246 return 1.0; 247 } 248 249 virtual sp<MediaPlayerBase> createPlayer() { 250 ALOGV(" create NuPlayer"); 251 return new NuPlayerDriver; 252 } 253}; 254 255class TestPlayerFactory : public MediaPlayerFactory::IFactory { 256 public: 257 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 258 const char* url, 259 float /*curScore*/) { 260 if (TestPlayerStub::canBeUsed(url)) { 261 return 1.0; 262 } 263 264 return 0.0; 265 } 266 267 virtual sp<MediaPlayerBase> createPlayer() { 268 ALOGV("Create Test Player stub"); 269 return new TestPlayerStub(); 270 } 271}; 272 273void MediaPlayerFactory::registerBuiltinFactories() { 274 Mutex::Autolock lock_(&sLock); 275 276 if (sInitComplete) 277 return; 278 279 registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER); 280 registerFactory_l(new NuPlayerFactory(), NU_PLAYER); 281 registerFactory_l(new TestPlayerFactory(), TEST_PLAYER); 282 283 sInitComplete = true; 284} 285 286} // namespace android 287