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 #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