blob: f5ec20c389072e0c2929c9a5959cda4c997d6604 [file] [log] [blame]
John Grossman44a7e422012-06-21 17:29:24 -07001/*
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
Marco Nelissen08b9e2d2014-12-16 12:46:34 -080018//#define LOG_NDEBUG 0
John Grossman44a7e422012-06-21 17:29:24 -070019#define LOG_TAG "MediaPlayerFactory"
20#include <utils/Log.h>
21
22#include <cutils/properties.h>
23#include <media/IMediaPlayer.h>
Lajos Molnarca7b4bc2014-12-05 17:14:54 -080024#include <media/stagefright/DataSource.h>
25#include <media/stagefright/FileSource.h>
John Grossman44a7e422012-06-21 17:29:24 -070026#include <media/stagefright/foundation/ADebug.h>
27#include <utils/Errors.h>
28#include <utils/misc.h>
Lajos Molnarca7b4bc2014-12-05 17:14:54 -080029#include <../libstagefright/include/WVMExtractor.h>
John Grossman44a7e422012-06-21 17:29:24 -070030
31#include "MediaPlayerFactory.h"
32
John Grossman44a7e422012-06-21 17:29:24 -070033#include "TestPlayerStub.h"
John Grossman44a7e422012-06-21 17:29:24 -070034#include "nuplayer/NuPlayerDriver.h"
35
36namespace android {
37
John Grossman44a7e422012-06-21 17:29:24 -070038Mutex 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
Andy Hung48f36a02014-09-03 23:28:52 +000065static player_type getDefaultPlayerType() {
Lajos Molnarf5bdd772014-07-27 21:22:11 -070066 return NU_PLAYER;
John Grossman44a7e422012-06-21 17:29:24 -070067}
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) { \
Andreas Huber198a8932013-02-05 13:16:39 -080099 ret = getDefaultPlayerType(); \
John Grossman44a7e422012-06-21 17:29:24 -0700100 } \
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
Chris Watkins99f31602015-03-20 13:06:33 -0700121player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
122 const sp<DataSource> &source) {
123 GET_PLAYER_TYPE_IMPL(client, source);
124}
125
John Grossman44a7e422012-06-21 17:29:24 -0700126#undef GET_PLAYER_TYPE_IMPL
127
128sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
129 player_type playerType,
Pawin Vongmasac7fe1652017-12-12 01:56:40 -0800130 const sp<MediaPlayerBase::Listener> &listener,
Ronghua Wu68845c12015-07-21 09:50:48 -0700131 pid_t pid) {
John Grossman44a7e422012-06-21 17:29:24 -0700132 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);
Ronghua Wu68845c12015-07-21 09:50:48 -0700145 p = factory->createPlayer(pid);
John Grossman44a7e422012-06-21 17:29:24 -0700146
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) {
Pawin Vongmasac7fe1652017-12-12 01:56:40 -0800155 p->setNotifyCallback(listener);
John Grossman44a7e422012-06-21 17:29:24 -0700156 } 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
John Grossman44a7e422012-06-21 17:29:24 -0700171class NuPlayerFactory : public MediaPlayerFactory::IFactory {
172 public:
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700173 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
John Grossman44a7e422012-06-21 17:29:24 -0700174 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)
Andreas Huber99759402013-04-01 14:28:31 -0700182 || !strncasecmp("https://", url, 8)
183 || !strncasecmp("file://", url, 7)) {
John Grossman44a7e422012-06-21 17:29:24 -0700184 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 }
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100192
193 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
194 return kOurScore;
195 }
John Grossman44a7e422012-06-21 17:29:24 -0700196 }
197
198 if (!strncasecmp("rtsp://", url, 7)) {
199 return kOurScore;
200 }
201
202 return 0.0;
203 }
204
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700205 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
206 const sp<IStreamSource>& /*source*/,
207 float /*curScore*/) {
John Grossman44a7e422012-06-21 17:29:24 -0700208 return 1.0;
209 }
210
Chris Watkins99f31602015-03-20 13:06:33 -0700211 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
Ronghua Wu68845c12015-07-21 09:50:48 -0700218 virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
John Grossman44a7e422012-06-21 17:29:24 -0700219 ALOGV(" create NuPlayer");
Ronghua Wu68845c12015-07-21 09:50:48 -0700220 return new NuPlayerDriver(pid);
John Grossman44a7e422012-06-21 17:29:24 -0700221 }
222};
223
John Grossman44a7e422012-06-21 17:29:24 -0700224class TestPlayerFactory : public MediaPlayerFactory::IFactory {
225 public:
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700226 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
John Grossman44a7e422012-06-21 17:29:24 -0700227 const char* url,
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700228 float /*curScore*/) {
John Grossman44a7e422012-06-21 17:29:24 -0700229 if (TestPlayerStub::canBeUsed(url)) {
230 return 1.0;
231 }
232
233 return 0.0;
234 }
235
Ronghua Wu68845c12015-07-21 09:50:48 -0700236 virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
John Grossman44a7e422012-06-21 17:29:24 -0700237 ALOGV("Create Test Player stub");
238 return new TestPlayerStub();
239 }
240};
241
John Grossman44a7e422012-06-21 17:29:24 -0700242void MediaPlayerFactory::registerBuiltinFactories() {
243 Mutex::Autolock lock_(&sLock);
244
245 if (sInitComplete)
246 return;
247
John Grossman44a7e422012-06-21 17:29:24 -0700248 registerFactory_l(new NuPlayerFactory(), NU_PLAYER);
John Grossman44a7e422012-06-21 17:29:24 -0700249 registerFactory_l(new TestPlayerFactory(), TEST_PLAYER);
250
John Grossman44a7e422012-06-21 17:29:24 -0700251 sInitComplete = true;
252}
253
254} // namespace android