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 36 namespace android { 37 38 Mutex MediaPlayerFactory::sLock; 39 MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap; 40 bool MediaPlayerFactory::sInitComplete = false; 41 42 status_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 65 static player_type getDefaultPlayerType() { 66 return NU_PLAYER; 67 } 68 69 status_t MediaPlayerFactory::registerFactory(IFactory* factory, 70 player_type type) { 71 Mutex::Autolock lock_(&sLock); 72 return registerFactory_l(factory, type); 73 } 74 75 void 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 104 player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 105 const char* url) { 106 GET_PLAYER_TYPE_IMPL(client, url); 107 } 108 109 player_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 116 player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client, 117 const sp<IStreamSource> &source) { 118 GET_PLAYER_TYPE_IMPL(client, source); 119 } 120 121 player_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 128 sp<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 172 class 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 225 class 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 243 void 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