blob: e9aaa848b89d1a2926c09e24e3f14f928d26a255 [file] [log] [blame]
Andreas Huber20111aa2009-07-14 16:56:47 -07001/*
2 * Copyright (C) 2009 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Chong Zhang3de157d2014-08-05 20:54:44 -070016//#define LOG_NDEBUG 0
17#define LOG_TAG "DataSource"
Andreas Huber20111aa2009-07-14 16:56:47 -070018
Chris Watkins99f31602015-03-20 13:06:33 -070019#include "include/CallbackDataSource.h"
Marco Nelissen56997122012-08-28 15:09:49 -070020#include "include/HTTPBase.h"
Marco Nelissen56997122012-08-28 15:09:49 -070021#include "include/NuCachedSource2.h"
Andreas Huber093437c2010-05-20 14:56:53 -070022
Andy Hungd49dbd62016-07-07 14:20:35 -070023#include <media/IDataSource.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080024#include <media/IMediaHTTPConnection.h>
25#include <media/IMediaHTTPService.h>
Chong Zhang3de157d2014-08-05 20:54:44 -070026#include <media/stagefright/foundation/ADebug.h>
Andreas Huber5a1c3522010-08-25 11:09:41 -070027#include <media/stagefright/foundation/AMessage.h>
Dongwon Kang60761282017-10-09 11:16:48 -070028#include <media/stagefright/foundation/ByteUtils.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070029#include <media/stagefright/DataSource.h>
Andreas Huber4bbfff22014-02-10 14:40:45 -080030#include <media/stagefright/DataURISource.h>
Andreas Huberfc9ba092010-01-11 15:35:19 -080031#include <media/stagefright/FileSource.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070032#include <media/stagefright/MediaErrors.h>
Andreas Huber1b86fe02014-01-29 11:13:26 -080033#include <media/stagefright/MediaHTTP.h>
Andy Hungd49dbd62016-07-07 14:20:35 -070034#include <media/stagefright/RemoteDataSource.h>
Andreas Huber20111aa2009-07-14 16:56:47 -070035#include <utils/String8.h>
36
Gloria Wanga8908292010-10-29 14:50:17 -070037#include <cutils/properties.h>
38
Marco Nelissen3001a8a2015-12-18 14:17:18 -080039#include <private/android_filesystem_config.h>
40
Andreas Huber20111aa2009-07-14 16:56:47 -070041namespace android {
42
James Dongc7fc37a2010-11-16 14:04:54 -080043bool DataSource::getUInt16(off64_t offset, uint16_t *x) {
Andreas Huber693d2712009-08-14 14:37:10 -070044 *x = 0;
45
46 uint8_t byte[2];
Andreas Huber34769bc2009-10-23 10:22:30 -070047 if (readAt(offset, byte, 2) != 2) {
Andreas Huber693d2712009-08-14 14:37:10 -070048 return false;
49 }
50
51 *x = (byte[0] << 8) | byte[1];
52
53 return true;
54}
55
Marco Nelissenec771222013-04-08 14:30:57 -070056bool DataSource::getUInt24(off64_t offset, uint32_t *x) {
57 *x = 0;
58
59 uint8_t byte[3];
60 if (readAt(offset, byte, 3) != 3) {
61 return false;
62 }
63
64 *x = (byte[0] << 16) | (byte[1] << 8) | byte[2];
65
66 return true;
67}
68
Marco Nelissen05f625c2013-02-13 09:27:28 -080069bool DataSource::getUInt32(off64_t offset, uint32_t *x) {
70 *x = 0;
71
72 uint32_t tmp;
73 if (readAt(offset, &tmp, 4) != 4) {
74 return false;
75 }
76
77 *x = ntohl(tmp);
78
79 return true;
80}
81
82bool DataSource::getUInt64(off64_t offset, uint64_t *x) {
83 *x = 0;
84
85 uint64_t tmp;
86 if (readAt(offset, &tmp, 8) != 8) {
87 return false;
88 }
89
90 *x = ntoh64(tmp);
91
92 return true;
93}
94
Chong Zhangb51ca282017-07-26 16:25:28 -070095bool DataSource::getUInt16Var(off64_t offset, uint16_t *x, size_t size) {
96 if (size == 2) {
97 return getUInt16(offset, x);
98 }
99 if (size == 1) {
100 uint8_t tmp;
101 if (readAt(offset, &tmp, 1) == 1) {
102 *x = tmp;
103 return true;
104 }
105 }
106 return false;
107}
108
109bool DataSource::getUInt32Var(off64_t offset, uint32_t *x, size_t size) {
110 if (size == 4) {
111 return getUInt32(offset, x);
112 }
113 if (size == 2) {
114 uint16_t tmp;
115 if (getUInt16(offset, &tmp)) {
116 *x = tmp;
117 return true;
118 }
119 }
120 return false;
121}
122
123bool DataSource::getUInt64Var(off64_t offset, uint64_t *x, size_t size) {
124 if (size == 8) {
125 return getUInt64(offset, x);
126 }
127 if (size == 4) {
128 uint32_t tmp;
129 if (getUInt32(offset, &tmp)) {
130 *x = tmp;
131 return true;
132 }
133 }
134 return false;
135}
136
James Dongc7fc37a2010-11-16 14:04:54 -0800137status_t DataSource::getSize(off64_t *size) {
Andreas Huber20111aa2009-07-14 16:56:47 -0700138 *size = 0;
139
140 return ERROR_UNSUPPORTED;
141}
142
Andy Hungd49dbd62016-07-07 14:20:35 -0700143sp<IDataSource> DataSource::getIDataSource() const {
144 return nullptr;
145}
146
Andreas Huber20111aa2009-07-14 16:56:47 -0700147////////////////////////////////////////////////////////////////////////////////
148
Andreas Huberfc9ba092010-01-11 15:35:19 -0800149// static
Andreas Huber5561ccf2010-01-27 16:49:05 -0800150sp<DataSource> DataSource::CreateFromURI(
Andreas Huber1b86fe02014-01-29 11:13:26 -0800151 const sp<IMediaHTTPService> &httpService,
152 const char *uri,
Chong Zhang3de157d2014-08-05 20:54:44 -0700153 const KeyedVector<String8, String8> *headers,
Robert Shih360d6d02014-09-29 14:42:35 -0700154 String8 *contentType,
155 HTTPBase *httpSource) {
Chong Zhangd354d8d2014-08-20 13:09:58 -0700156 if (contentType != NULL) {
157 *contentType = "";
Chong Zhang3de157d2014-08-05 20:54:44 -0700158 }
159
Andreas Huberfc9ba092010-01-11 15:35:19 -0800160 sp<DataSource> source;
161 if (!strncasecmp("file://", uri, 7)) {
162 source = new FileSource(uri + 7);
Jeff Tinker29b7dcf2016-10-24 10:28:30 -0700163 } else if (!strncasecmp("http://", uri, 7) || !strncasecmp("https://", uri, 8)) {
Chong Zhang217bde82014-09-22 12:25:36 -0700164 if (httpService == NULL) {
165 ALOGE("Invalid http service!");
166 return NULL;
167 }
168
Robert Shih360d6d02014-09-29 14:42:35 -0700169 if (httpSource == NULL) {
170 sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
171 if (conn == NULL) {
172 ALOGE("Failed to make http connection from http service!");
173 return NULL;
174 }
175 httpSource = new MediaHTTP(conn);
Chong Zhang217bde82014-09-22 12:25:36 -0700176 }
177
Chong Zhang7b3cd1f2014-08-13 15:26:49 -0700178 String8 cacheConfig;
Caroline Tice65c954e2017-02-08 11:33:04 -0800179 bool disconnectAtHighwatermark = false;
Chong Zhang7b3cd1f2014-08-13 15:26:49 -0700180 KeyedVector<String8, String8> nonCacheSpecificHeaders;
181 if (headers != NULL) {
182 nonCacheSpecificHeaders = *headers;
183 NuCachedSource2::RemoveCacheSpecificHeaders(
184 &nonCacheSpecificHeaders,
185 &cacheConfig,
186 &disconnectAtHighwatermark);
187 }
188
189 if (httpSource->connect(uri, &nonCacheSpecificHeaders) != OK) {
Chong Zhang3de157d2014-08-05 20:54:44 -0700190 ALOGE("Failed to connect http source!");
Andreas Hubere94bd142010-03-12 08:59:22 -0800191 return NULL;
192 }
Andreas Huber918c7652012-04-13 11:16:48 -0700193
Jeff Tinker29b7dcf2016-10-24 10:28:30 -0700194 if (contentType != NULL) {
195 *contentType = httpSource->getMIMEType();
Andreas Huber16087352012-04-13 14:54:36 -0700196 }
Jeff Tinker29b7dcf2016-10-24 10:28:30 -0700197
198 source = NuCachedSource2::Create(
199 httpSource,
200 cacheConfig.isEmpty() ? NULL : cacheConfig.string(),
201 disconnectAtHighwatermark);
Andreas Huber4bbfff22014-02-10 14:40:45 -0800202 } else if (!strncasecmp("data:", uri, 5)) {
203 source = DataURISource::Create(uri);
Andreas Huberfc9ba092010-01-11 15:35:19 -0800204 } else {
205 // Assume it's a filename.
206 source = new FileSource(uri);
207 }
208
209 if (source == NULL || source->initCheck() != OK) {
210 return NULL;
211 }
212
213 return source;
214}
215
Andy Hungd49dbd62016-07-07 14:20:35 -0700216sp<DataSource> DataSource::CreateFromFd(int fd, int64_t offset, int64_t length) {
217 sp<FileSource> source = new FileSource(fd, offset, length);
218 return source->initCheck() != OK ? nullptr : source;
219}
220
Robert Shih360d6d02014-09-29 14:42:35 -0700221sp<DataSource> DataSource::CreateMediaHTTP(const sp<IMediaHTTPService> &httpService) {
222 if (httpService == NULL) {
223 return NULL;
224 }
225
226 sp<IMediaHTTPConnection> conn = httpService->makeHTTPConnection();
227 if (conn == NULL) {
228 return NULL;
229 } else {
230 return new MediaHTTP(conn);
231 }
232}
233
Chris Watkins99f31602015-03-20 13:06:33 -0700234sp<DataSource> DataSource::CreateFromIDataSource(const sp<IDataSource> &source) {
Chris Watkinsda7e4532015-04-07 10:01:15 -0700235 return new TinyCacheSource(new CallbackDataSource(source));
Chris Watkins99f31602015-03-20 13:06:33 -0700236}
237
Andreas Huber6511c972011-03-30 11:15:27 -0700238String8 DataSource::getMIMEType() const {
239 return String8("application/octet-stream");
240}
241
Andy Hungd49dbd62016-07-07 14:20:35 -0700242sp<IDataSource> DataSource::asIDataSource() {
243 return RemoteDataSource::wrap(sp<DataSource>(this));
244}
245
Andreas Huber20111aa2009-07-14 16:56:47 -0700246} // namespace android