• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
registerFactory_l(IFactory * factory,player_type type)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 
getDefaultPlayerType()65 static player_type getDefaultPlayerType() {
66     return NU_PLAYER;
67 }
68 
registerFactory(IFactory * factory,player_type type)69 status_t MediaPlayerFactory::registerFactory(IFactory* factory,
70                                              player_type type) {
71     Mutex::Autolock lock_(&sLock);
72     return registerFactory_l(factory, type);
73 }
74 
unregisterFactory(player_type type)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 
getPlayerType(const sp<IMediaPlayer> & client,const char * url)104 player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
105                                               const char* url) {
106     GET_PLAYER_TYPE_IMPL(client, url);
107 }
108 
getPlayerType(const sp<IMediaPlayer> & client,int fd,int64_t offset,int64_t length)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 
getPlayerType(const sp<IMediaPlayer> & client,const sp<IStreamSource> & source)116 player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
117                                               const sp<IStreamSource> &source) {
118     GET_PLAYER_TYPE_IMPL(client, source);
119 }
120 
getPlayerType(const sp<IMediaPlayer> & client,const sp<DataSource> & source)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 
createPlayer(player_type playerType,void * cookie,notify_callback_f notifyFunc,pid_t pid)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:
scoreFactory(const sp<IMediaPlayer> &,const char * url,float curScore)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 
scoreFactory(const sp<IMediaPlayer> &,const sp<IStreamSource> &,float)206     virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
207                                const sp<IStreamSource>& /*source*/,
208                                float /*curScore*/) {
209         return 1.0;
210     }
211 
scoreFactory(const sp<IMediaPlayer> &,const sp<DataSource> &,float)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 
createPlayer(pid_t pid)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:
scoreFactory(const sp<IMediaPlayer> &,const char * url,float)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 
createPlayer(pid_t)237     virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
238         ALOGV("Create Test Player stub");
239         return new TestPlayerStub();
240     }
241 };
242 
registerBuiltinFactories()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