2 * Copyright 2012 Michael Chen <omxcodec@gmail.com>
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
8 * http://www.apache.org/licenses/LICENSE-2.0
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.
17 //#define LOG_NDEBUG 0
18 #define LOG_TAG "FFMPEG"
19 #include <utils/Log.h>
22 #include "ffmpeg_source.h"
24 #include <media/stagefright/DataSource.h>
31 #include "libavformat/url.h"
42 FFSource(DataSource *source);
44 int read(unsigned char *buf, size_t size);
45 int64_t seek(int64_t pos);
49 sp<DataSource> mSource;
53 FFSource::FFSource(DataSource *source)
64 int FFSource::init_check()
66 if (mSource->initCheck() != OK) {
67 ALOGE("FFSource initCheck failed");
74 int FFSource::read(unsigned char *buf, size_t size)
78 n = mSource->readAt(mOffset, buf, size);
79 if (n == UNKNOWN_ERROR) {
80 ALOGE("FFSource readAt failed");
81 return AVERROR(errno);
90 int64_t FFSource::seek(int64_t pos)
96 off64_t FFSource::getSize()
100 if (mSource->getSize(&sz) != OK) {
101 ALOGE("FFSource getSize failed");
102 return AVERROR(errno);
108 /////////////////////////////////////////////////////////////////
110 static int android_open(URLContext *h, const char *url, int flags __unused)
112 // the url in form of "android-source:<DataSource Ptr>",
113 // the DataSource Pointer passed by the ffmpeg extractor
114 DataSource *source = NULL;
115 char url_check[PATH_MAX] = {0};
117 ALOGV("android source begin open");
120 ALOGE("android url is null!");
124 ALOGV("android open, url: %s", url);
125 sscanf(url + strlen("android-source:"), "%p", &source);
127 ALOGE("ffmpeg open data source error! (invalid source)");
131 snprintf(url_check, sizeof(url_check), "android-source:%p",
134 if (strcmp(url_check, url) != 0) {
136 String8 uri = source->getUri();
138 ALOGE("ffmpeg open data source error! (source uri)");
142 snprintf(url_check, sizeof(url_check), "android-source:%p|file:%s",
143 source, uri.string());
145 if (strcmp(url_check, url) != 0) {
146 ALOGE("ffmpeg open data source error! (url check)");
151 ALOGV("ffmpeg open android data source success, source ptr: %p", source);
153 FFSource *ffs = new FFSource(source);
154 h->priv_data = (void *)ffs;
156 ALOGV("android source open success");
160 static int android_read(URLContext *h, unsigned char *buf, int size)
162 FFSource* ffs = (FFSource *)h->priv_data;
163 return ffs->read(buf, size);
166 static int android_write(URLContext *h __unused, const unsigned char *buf __unused, int size __unused)
171 static int64_t android_seek(URLContext *h, int64_t pos, int whence)
173 FFSource* ffs = (FFSource*)h->priv_data;
175 if (whence == AVSEEK_SIZE) {
176 return ffs->getSize();
183 static int android_close(URLContext *h)
185 FFSource* ffs = (FFSource*)h->priv_data;
186 ALOGV("android source close");
192 static int android_get_handle(URLContext *h)
194 return (intptr_t)h->priv_data;
197 static int android_check(URLContext *h, int mask)
199 FFSource* ffs = (FFSource*)h->priv_data;
201 /* url_check does not guarantee url_open will be called
202 * (and actually it is not designed to do so)
203 * If url_open is not called before url_check called, ffs
204 * will be null, and we will assume everything is ok.
206 if (ffs && (ffs->init_check() < 0))
207 return AVERROR(EACCES); // FIXME
209 return (mask & AVIO_FLAG_READ);
212 static URLProtocol ff_android_protocol;
214 void ffmpeg_register_android_source()
216 memset(&ff_android_protocol, 0, sizeof(URLProtocol));
217 ff_android_protocol.name = "android-source";
218 ff_android_protocol.url_open = android_open;
219 ff_android_protocol.url_read = android_read;
220 ff_android_protocol.url_write = android_write;
221 ff_android_protocol.url_seek = android_seek;
222 ff_android_protocol.url_close = android_close;
223 ff_android_protocol.url_get_file_handle = android_get_handle;
224 ff_android_protocol.url_check = android_check;
226 ffurl_register_protocol(&ff_android_protocol);
229 } // namespace android