MediaPlayerFactory.cpp revision 01854c0129245d034bd99d64817dce06df20c5a6
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 "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 return NU_PLAYER; 67} 68 69status_t MediaPlayerFactory::registerFactory(IFactory* factory, 70 player_type type) { 71 Mutex::Autolock lock_(&sLock); 72 return registerFactory_l(factory, type); 73} 74 75void MediaPlayerFactory::unregisterFactory(player_type type) { 76 Mutex::Autolock lock_(&sLock); 77 sFactoryMap.removeItem(type); 78} 79 80#define GET_PLAYER_TYPE_IMPL(a...) \ 81 Mutex::Autolock lock_(&sLock); \ 82 \ 83 player_type ret = STAGEFRIGHT_PLAYER; \ 84 float bestScore = 0.0; \ 85 \ 86 for (size_t i = 0; i < sFactoryMap.size(); ++i) { \ 87 \ 88 IFactory* v = sFactoryMap.valueAt(i); \ 89 float thisScore; \ 90 CHECK(v != NULL); \ 91 thisScore = v->scoreFactory(a, bestScore); \ 92 if (thisScore > bestScore) { \ 93 ret = sFactoryMap.keyAt(i); \ 94 bestScore = thisScore; \ 95 } \ 96 } \ 97 \ 98 if (0.0 == bestScore) { \ 99 ret = getDefaultPlayerType(); \ 100 } \ 101 \ 102 return ret; 103 104player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 105 const char* url) { 106 GET_PLAYER_TYPE_IMPL(client, url); 107} 108 109player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 110 int fd, 111 int64_t offset, 112 int64_t length) { 113 GET_PLAYER_TYPE_IMPL(client, fd, offset, length); 114} 115 116player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 117 const sp<IStreamSource> &source) { 118 GET_PLAYER_TYPE_IMPL(client, source); 119} 120 121player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 122 const sp<DataSource> &source) { 123 GET_PLAYER_TYPE_IMPL(client, source); 124} 125 126#undef GET_PLAYER_TYPE_IMPL 127 128sp<MediaPlayerBase> MediaPlayerFactory::createPlayer( 129 player_type playerType, 130 void* cookie, 131 notify_callback_f notifyFunc, 132 pid_t pid) { 133 sp<MediaPlayerBase> p; 134 IFactory* factory; 135 status_t init_result; 136 Mutex::Autolock lock_(&sLock); 137 138 if (sFactoryMap.indexOfKey(playerType) < 0) { 139 ALOGE("Failed to create player object of type %d, no registered" 140 " factory", playerType); 141 return p; 142 } 143 144 factory = sFactoryMap.valueFor(playerType); 145 CHECK(NULL != factory); 146 p = factory->createPlayer(pid); 147 148 if (p == NULL) { 149 ALOGE("Failed to create player object of type %d, create failed", 150 playerType); 151 return p; 152 } 153 154 init_result = p->initCheck(); 155 if (init_result == NO_ERROR) { 156 p->setNotifyCallback(cookie, notifyFunc); 157 } else { 158 ALOGE("Failed to create player object of type %d, initCheck failed" 159 " (res = %d)", playerType, init_result); 160 p.clear(); 161 } 162 163 return p; 164} 165 166/***************************************************************************** 167 * * 168 * Built-In Factory Implementations * 169 * * 170 *****************************************************************************/ 171 172class NuPlayerFactory : public MediaPlayerFactory::IFactory { 173 public: 174 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 175 const char* url, 176 float curScore) { 177 static const float kOurScore = 0.8; 178 179 if (kOurScore <= curScore) 180 return 0.0; 181 182 if (!strncasecmp("http://", url, 7) 183 || !strncasecmp("https://", url, 8) 184 || !strncasecmp("file://", url, 7)) { 185 size_t len = strlen(url); 186 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) { 187 return kOurScore; 188 } 189 190 if (strstr(url,"m3u8")) { 191 return kOurScore; 192 } 193 194 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) { 195 return kOurScore; 196 } 197 } 198 199 if (!strncasecmp("rtsp://", url, 7)) { 200 return kOurScore; 201 } 202 203 return 0.0; 204 } 205 206 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 207 const sp<IStreamSource>& /*source*/, 208 float /*curScore*/) { 209 return 1.0; 210 } 211 212 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 213 const sp<DataSource>& /*source*/, 214 float /*curScore*/) { 215 // Only NuPlayer supports setting a DataSource source directly. 216 return 1.0; 217 } 218 219 virtual sp<MediaPlayerBase> createPlayer(pid_t pid) { 220 ALOGV(" create NuPlayer"); 221 return new NuPlayerDriver(pid); 222 } 223}; 224 225class TestPlayerFactory : public MediaPlayerFactory::IFactory { 226 public: 227 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/, 228 const char* url, 229 float /*curScore*/) { 230 if (TestPlayerStub::canBeUsed(url)) { 231 return 1.0; 232 } 233 234 return 0.0; 235 } 236 237 virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) { 238 ALOGV("Create Test Player stub"); 239 return new TestPlayerStub(); 240 } 241}; 242 243void MediaPlayerFactory::registerBuiltinFactories() { 244 Mutex::Autolock lock_(&sLock); 245 246 if (sInitComplete) 247 return; 248 249 registerFactory_l(new NuPlayerFactory(), NU_PLAYER); 250 registerFactory_l(new TestPlayerFactory(), TEST_PLAYER); 251 252 sInitComplete = true; 253} 254 255} // namespace android 256