blob: ca7b96ff381706ccabae2e8d51f541fa4b570c85 [file] [log] [blame]
Wei Jia53692fa2017-12-11 10:33:46 -08001/*
2**
3** Copyright 2017, 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 "MediaPlayer2Factory"
20#include <utils/Log.h>
21
22#include <cutils/properties.h>
23#include <media/DataSource.h>
24#include <media/MediaPlayer2Engine.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 "MediaPlayer2Factory.h"
31
32#include "TestPlayerStub.h"
33#include "nuplayer2/NuPlayer2Driver.h"
34
35namespace android {
36
37Mutex MediaPlayer2Factory::sLock;
38MediaPlayer2Factory::tFactoryMap MediaPlayer2Factory::sFactoryMap;
39bool MediaPlayer2Factory::sInitComplete = false;
40
41status_t MediaPlayer2Factory::registerFactory_l(IFactory* factory,
42 player2_type type) {
43 if (NULL == factory) {
44 ALOGE("Failed to register MediaPlayer2Factory 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 MediaPlayer2Factory 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 MediaPlayer2Factory of type %d, failed to add"
57 " to map.", type);
58 return UNKNOWN_ERROR;
59 }
60
61 return OK;
62}
63
64static player2_type getDefaultPlayerType() {
65 return PLAYER2_NU_PLAYER2;
66}
67
68status_t MediaPlayer2Factory::registerFactory(IFactory* factory,
69 player2_type type) {
70 Mutex::Autolock lock_(&sLock);
71 return registerFactory_l(factory, type);
72}
73
74void MediaPlayer2Factory::unregisterFactory(player2_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 player2_type ret = PLAYER2_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
103player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
104 const char* url) {
105 GET_PLAYER_TYPE_IMPL(client, url);
106}
107
108player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
109 int fd,
110 int64_t offset,
111 int64_t length) {
112 GET_PLAYER_TYPE_IMPL(client, fd, offset, length);
113}
114
115player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
116 const sp<IStreamSource> &source) {
117 GET_PLAYER_TYPE_IMPL(client, source);
118}
119
120player2_type MediaPlayer2Factory::getPlayerType(const sp<MediaPlayer2Engine>& client,
121 const sp<DataSource> &source) {
122 GET_PLAYER_TYPE_IMPL(client, source);
123}
124
125#undef GET_PLAYER_TYPE_IMPL
126
127sp<MediaPlayer2Base> MediaPlayer2Factory::createPlayer(
128 player2_type playerType,
129 void* cookie,
130 notify_callback_f notifyFunc,
131 pid_t pid) {
132 sp<MediaPlayer2Base> 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
171class NuPlayer2Factory : public MediaPlayer2Factory::IFactory {
172 public:
173 virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*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
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<MediaPlayer2Engine>& /*client*/,
207 const sp<IStreamSource>& /*source*/,
208 float /*curScore*/) {
209 return 1.0;
210 }
211
212 virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*client*/,
213 const sp<DataSource>& /*source*/,
214 float /*curScore*/) {
215 // Only NuPlayer2 supports setting a DataSource source directly.
216 return 1.0;
217 }
218
219 virtual sp<MediaPlayer2Base> createPlayer(pid_t pid) {
220 ALOGV(" create NuPlayer2");
221 return new NuPlayer2Driver(pid);
222 }
223};
224
225class TestPlayerFactory : public MediaPlayer2Factory::IFactory {
226 public:
227 virtual float scoreFactory(const sp<MediaPlayer2Engine>& /*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<MediaPlayer2Base> createPlayer(pid_t /* pid */) {
238 ALOGV("Create Test Player stub");
239 return new TestPlayerStub();
240 }
241};
242
243void MediaPlayer2Factory::registerBuiltinFactories() {
244 Mutex::Autolock lock_(&sLock);
245
246 if (sInitComplete) {
247 return;
248 }
249
250 IFactory* factory = new NuPlayer2Factory();
251 if (registerFactory_l(factory, PLAYER2_NU_PLAYER2) != OK) {
252 delete factory;
253 }
254 factory = new TestPlayerFactory();
255 if (registerFactory_l(factory, PLAYER2_TEST_PLAYER) != OK) {
256 delete factory;
257 }
258
259 sInitComplete = true;
260}
261
262} // namespace android