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