blob: 05f7365594d3ebad45fae04ed2f807fdbc72f5a2 [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>
Marco Nelissenfa8be7d2019-09-23 12:15:57 -070023#include <datasource/FileSource.h>
Dongwon Kangd91dc5a2017-10-10 00:07:09 -070024#include <media/DataSource.h>
John Grossman44a7e422012-06-21 17:29:24 -070025#include <media/IMediaPlayer.h>
26#include <media/stagefright/foundation/ADebug.h>
27#include <utils/Errors.h>
28#include <utils/misc.h>
29
30#include "MediaPlayerFactory.h"
31
John Grossman44a7e422012-06-21 17:29:24 -070032#include "TestPlayerStub.h"
John Grossman44a7e422012-06-21 17:29:24 -070033#include "nuplayer/NuPlayerDriver.h"
34
35namespace android {
36
John Grossman44a7e422012-06-21 17:29:24 -070037Mutex MediaPlayerFactory::sLock;
38MediaPlayerFactory::tFactoryMap MediaPlayerFactory::sFactoryMap;
39bool MediaPlayerFactory::sInitComplete = false;
40
41status_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
Andy Hung48f36a02014-09-03 23:28:52 +000064static player_type getDefaultPlayerType() {
Lajos Molnarf5bdd772014-07-27 21:22:11 -070065 return NU_PLAYER;
John Grossman44a7e422012-06-21 17:29:24 -070066}
67
68status_t MediaPlayerFactory::registerFactory(IFactory* factory,
69 player_type type) {
70 Mutex::Autolock lock_(&sLock);
71 return registerFactory_l(factory, type);
72}
73
74void 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) { \
Andreas Huber198a8932013-02-05 13:16:39 -080098 ret = getDefaultPlayerType(); \
John Grossman44a7e422012-06-21 17:29:24 -070099 } \
100 \
101 return ret;
102
103player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
104 const char* url) {
105 GET_PLAYER_TYPE_IMPL(client, url);
106}
107
108player_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
115player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
116 const sp<IStreamSource> &source) {
117 GET_PLAYER_TYPE_IMPL(client, source);
118}
119
Chris Watkins99f31602015-03-20 13:06:33 -0700120player_type MediaPlayerFactory::getPlayerType(const sp<IMediaPlayer>& client,
121 const sp<DataSource> &source) {
122 GET_PLAYER_TYPE_IMPL(client, source);
123}
124
John Grossman44a7e422012-06-21 17:29:24 -0700125#undef GET_PLAYER_TYPE_IMPL
126
127sp<MediaPlayerBase> MediaPlayerFactory::createPlayer(
128 player_type playerType,
Pawin Vongmasa082e4f72017-12-17 02:31:18 -0800129 const sp<MediaPlayerBase::Listener> &listener,
Ronghua Wu68845c12015-07-21 09:50:48 -0700130 pid_t pid) {
John Grossman44a7e422012-06-21 17:29:24 -0700131 sp<MediaPlayerBase> p;
132 IFactory* factory;
133 status_t init_result;
134 Mutex::Autolock lock_(&sLock);
135
136 if (sFactoryMap.indexOfKey(playerType) < 0) {
137 ALOGE("Failed to create player object of type %d, no registered"
138 " factory", playerType);
139 return p;
140 }
141
142 factory = sFactoryMap.valueFor(playerType);
143 CHECK(NULL != factory);
Ronghua Wu68845c12015-07-21 09:50:48 -0700144 p = factory->createPlayer(pid);
John Grossman44a7e422012-06-21 17:29:24 -0700145
146 if (p == NULL) {
147 ALOGE("Failed to create player object of type %d, create failed",
148 playerType);
149 return p;
150 }
151
152 init_result = p->initCheck();
153 if (init_result == NO_ERROR) {
Pawin Vongmasa082e4f72017-12-17 02:31:18 -0800154 p->setNotifyCallback(listener);
John Grossman44a7e422012-06-21 17:29:24 -0700155 } else {
156 ALOGE("Failed to create player object of type %d, initCheck failed"
157 " (res = %d)", playerType, init_result);
158 p.clear();
159 }
160
161 return p;
162}
163
164/*****************************************************************************
165 * *
166 * Built-In Factory Implementations *
167 * *
168 *****************************************************************************/
169
John Grossman44a7e422012-06-21 17:29:24 -0700170class NuPlayerFactory : public MediaPlayerFactory::IFactory {
171 public:
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700172 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
John Grossman44a7e422012-06-21 17:29:24 -0700173 const char* url,
174 float curScore) {
175 static const float kOurScore = 0.8;
176
177 if (kOurScore <= curScore)
178 return 0.0;
179
180 if (!strncasecmp("http://", url, 7)
Andreas Huber99759402013-04-01 14:28:31 -0700181 || !strncasecmp("https://", url, 8)
182 || !strncasecmp("file://", url, 7)) {
John Grossman44a7e422012-06-21 17:29:24 -0700183 size_t len = strlen(url);
184 if (len >= 5 && !strcasecmp(".m3u8", &url[len - 5])) {
185 return kOurScore;
186 }
187
188 if (strstr(url,"m3u8")) {
189 return kOurScore;
190 }
Oscar Rydhé7a33b772012-02-20 10:15:48 +0100191
192 if ((len >= 4 && !strcasecmp(".sdp", &url[len - 4])) || strstr(url, ".sdp?")) {
193 return kOurScore;
194 }
John Grossman44a7e422012-06-21 17:29:24 -0700195 }
196
197 if (!strncasecmp("rtsp://", url, 7)) {
198 return kOurScore;
199 }
200
201 return 0.0;
202 }
203
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700204 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
205 const sp<IStreamSource>& /*source*/,
206 float /*curScore*/) {
John Grossman44a7e422012-06-21 17:29:24 -0700207 return 1.0;
208 }
209
Chris Watkins99f31602015-03-20 13:06:33 -0700210 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
211 const sp<DataSource>& /*source*/,
212 float /*curScore*/) {
213 // Only NuPlayer supports setting a DataSource source directly.
214 return 1.0;
215 }
216
Ronghua Wu68845c12015-07-21 09:50:48 -0700217 virtual sp<MediaPlayerBase> createPlayer(pid_t pid) {
John Grossman44a7e422012-06-21 17:29:24 -0700218 ALOGV(" create NuPlayer");
Ronghua Wu68845c12015-07-21 09:50:48 -0700219 return new NuPlayerDriver(pid);
John Grossman44a7e422012-06-21 17:29:24 -0700220 }
221};
222
John Grossman44a7e422012-06-21 17:29:24 -0700223class TestPlayerFactory : public MediaPlayerFactory::IFactory {
224 public:
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700225 virtual float scoreFactory(const sp<IMediaPlayer>& /*client*/,
John Grossman44a7e422012-06-21 17:29:24 -0700226 const char* url,
Mark Salyzyn247d9eb2014-06-23 14:14:40 -0700227 float /*curScore*/) {
John Grossman44a7e422012-06-21 17:29:24 -0700228 if (TestPlayerStub::canBeUsed(url)) {
229 return 1.0;
230 }
231
232 return 0.0;
233 }
234
Ronghua Wu68845c12015-07-21 09:50:48 -0700235 virtual sp<MediaPlayerBase> createPlayer(pid_t /* pid */) {
John Grossman44a7e422012-06-21 17:29:24 -0700236 ALOGV("Create Test Player stub");
237 return new TestPlayerStub();
238 }
239};
240
John Grossman44a7e422012-06-21 17:29:24 -0700241void MediaPlayerFactory::registerBuiltinFactories() {
242 Mutex::Autolock lock_(&sLock);
243
244 if (sInitComplete)
245 return;
246
Yunlian Jiang449d3f02017-06-27 15:51:41 -0700247 IFactory* factory = new NuPlayerFactory();
248 if (registerFactory_l(factory, NU_PLAYER) != OK)
249 delete factory;
250 factory = new TestPlayerFactory();
251 if (registerFactory_l(factory, TEST_PLAYER) != OK)
252 delete factory;
John Grossman44a7e422012-06-21 17:29:24 -0700253
John Grossman44a7e422012-06-21 17:29:24 -0700254 sInitComplete = true;
255}
256
257} // namespace android