MediaPlayerFactory.cpp revision 701d342f785e407c8e6bcb046658f84ac56d989a
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#include <../libstagefright/include/WVMExtractor.h> 30 31#include "MediaPlayerFactory.h" 32 33#include "TestPlayerStub.h" 34#include "StagefrightPlayer.h" 35#include "nuplayer/NuPlayerDriver.h" 36 37namespace android { 38 39Mutex MediaPlayerFactory::sLock; 40MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap; 41bool MediaPlayerFactory::sInitComplete = false; 42 43status_t MediaPlayerFactory::registerFactory_l(IFactory* factory, 44 player_type type) { 45 if (NULL == factory) { 46 ALOGE("Failed to register MediaPlayerFactory of type %d, factory is" 47 " NULL.", type); 48 return BAD_VALUE; 49 } 50 51 if (sFactoryMap.indexOfKey(type) >= 0) { 52 ALOGE("Failed to register MediaPlayerFactory of type %d, type is" 53 " already registered.", type); 54 return ALREADY_EXISTS; 55 } 56 57 if (sFactoryMap.add(type, factory) < 0) { 58 ALOGE("Failed to register MediaPlayerFactory of type %d, failed to add" 59 " to map.", type); 60 return UNKNOWN_ERROR; 61 } 62 63 return OK; 64} 65 66static player_type getDefaultPlayerType() { 67 char value[PROPERTY_VALUE_MAX]; 68 if (property_get("media.stagefright.use-awesome", value, NULL) 69 && (!strcmp("1", value) || !strcasecmp("true", value))) { 70 return STAGEFRIGHT_PLAYER; 71 } 72 73 return NU_PLAYER; 74} 75 76status_t MediaPlayerFactory::registerFactory(IFactory* factory, 77 player_type type) { 78 Mutex::Autolock lock_(&sLock); 79 return registerFactory_l(factory, type); 80} 81 82void MediaPlayerFactory::unregisterFactory(player_type type) { 83 Mutex::Autolock lock_(&sLock); 84 sFactoryMap.removeItem(type); 85} 86 87#define GET_PLAYER_TYPE_IMPL(a...) \ 88 Mutex::Autolock lock_(&sLock); \ 89 \ 90 player_type ret = STAGEFRIGHT_PLAYER; \ 91 float bestScore = 0.0; \ 92 \ 93 for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ 94 \ 95 IFactory* v = sFactoryMap.valueAt(i); \ 96 float thisScore; \ 97 CHECK(v != NULL); \ 98 thisScore = v->scoreFactory(a, bestScore); \ 99 if (thisScore > bestScore) { \ 100 ret = sFactoryMap.keyAt(i); \ 101 bestScore = thisScore; \ 102 } \ 103 } \ 104 \ 105 if (0.0 == bestScore) { \ 106 ret = getDefaultPlayerType(); \ 107 } \ 108 \ 109 return ret; 110 111player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 112 const char* url) { 113 GET_PLAYER_TYPE_IMPL(client, url); 114} 115 116player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 117 int fd, 118 int64_t offset, 119 int64_t length) { 120 GET_PLAYER_TYPE_IMPL(client, fd, offset, length); 121} 122 123player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 124 const sp<IStreamSource> &source) { 125 GET_PLAYER_TYPE_IMPL(client, source); 126} 127 128player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 129 const sp<DataSource> &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 (legacyDrm()) { 187 sp<DataSource> source = new FileSource(dup(fd), offset, length); 188 String8 mimeType; 189 float confidence; 190 if (SniffWVM(source, &mimeType, &confidence, NULL /* format */)) { 191 return 1.0; 192 } 193 } 194 195 if (getDefaultPlayerType() == STAGEFRIGHT_PLAYER) { 196 char buf[20]; 197 lseek(fd, offset, SEEK_SET); 198 read(fd, buf, sizeof(buf)); 199 lseek(fd, offset, SEEK_SET); 200 201 uint32_t ident = *((uint32_t*)buf); 202 203 // Ogg vorbis? 204 if (ident == 0x5367674f) // 'OggS' 205 return 1.0; 206 } 207 208 return 0.0; 209 } 210 211 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 212 const char* url, 213 float /*curScore*/) { 214 if (legacyDrm() && !strncasecmp("widevine://", url, 11)) { 215 return 1.0; 216 } 217 return 0.0; 218 } 219 220 virtual sp<MediaPlayerBase> createPlayer() { 221 ALOGV(" create StagefrightPlayer"); 222 return new StagefrightPlayer(); 223 } 224 private: 225 bool legacyDrm() { 226 char value[PROPERTY_VALUE_MAX]; 227 if (property_get("persist.sys.media.legacy-drm", value, NULL) 228 && (!strcmp("1", value) || !strcasecmp("true", value))) { 229 return true; 230 } 231 return false; 232 } 233}; 234 235class NuPlayerFactory : public MediaPlayerFactory::IFactory { 236 public: 237 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 238 const char* url, 239 float curScore) { 240 static const float kOurScore = 0.8; 241 242 if (kOurScore <= curScore) 243 return 0.0; 244 245 if (!strncasecmp("http://", url, 7) 246 || !strncasecmp("https://", url, 8) 247 || !strncasecmp("file://", url, 7)) { 248 size_t len = strlen(url); 249 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 250 return kOurScore; 251 } 252 253 if (strstr(url,"m3u8")) { 254 return kOurScore; 255 } 256 257 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) { 258 return kOurScore; 259 } 260 } 261 262 if (!strncasecmp("rtsp://", url, 7)) { 263 return kOurScore; 264 } 265 266 return 0.0; 267 } 268 269 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 270 const sp<IStreamSource>& /*source*/, 271 float /*curScore*/) { 272 return 1.0; 273 } 274 275 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 276 const sp<DataSource>& /*source*/, 277 float /*curScore*/) { 278 // Only NuPlayer supports setting a DataSource source directly. 279 return 1.0; 280 } 281 282 virtual sp<MediaPlayerBase> createPlayer() { 283 ALOGV(" create NuPlayer"); 284 return new NuPlayerDriver; 285 } 286}; 287 288class TestPlayerFactory : public MediaPlayerFactory::IFactory { 289 public: 290 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 291 const char* url, 292 float /*curScore*/) { 293 if (TestPlayerStub::canBeUsed(url)) { 294 return 1.0; 295 } 296 297 return 0.0; 298 } 299 300 virtual sp<MediaPlayerBase> createPlayer() { 301 ALOGV("Create Test Player stub"); 302 return new TestPlayerStub(); 303 } 304}; 305 306void MediaPlayerFactory::registerBuiltinFactories() { 307 Mutex::Autolock lock_(&sLock); 308 309 if (sInitComplete) 310 return; 311 312 registerFactory_l(new StagefrightPlayerFactory(), STAGEFRIGHT_PLAYER); 313 registerFactory_l(new NuPlayerFactory(), NU_PLAYER); 314 registerFactory_l(new TestPlayerFactory(), TEST_PLAYER); 315 316 sInitComplete = true; 317} 318 319} // namespace android 320