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_TAG "FFMPEG"
18 #include <utils/Log.h>
22 #include <media/stagefright/DataSource.h>
29 #include "libavformat/url.h"
40 FFSource(DataSource *source);
42 int read(unsigned char *buf, size_t size);
43 int64_t seek(int64_t pos);
47 sp<DataSource> mSource;
51 FFSource::FFSource(DataSource *source)
62 int FFSource::init_check()
64 if (mSource->initCheck() != OK) {
65 ALOGE("FFSource initCheck failed");
72 int FFSource::read(unsigned char *buf, size_t size)
76 n = mSource->readAt(mOffset, buf, size);
77 if (n == UNKNOWN_ERROR) {
78 ALOGE("FFSource readAt failed");
79 return AVERROR(errno);
87 int64_t FFSource::seek(int64_t pos)
93 off64_t FFSource::getSize()
97 if (mSource->getSize(&sz) != OK) {
98 ALOGE("FFSource getSize failed");
99 return AVERROR(errno);
105 /////////////////////////////////////////////////////////////////
107 static int android_open(URLContext *h, const char *url, int flags)
109 // the url in form of "android-source:<DataSource Ptr>",
110 // the DataSource Pointer passed by the ffmpeg extractor
111 DataSource *source = NULL;
113 ALOGD("android source begin open");
116 ALOGE("android url is null!");
120 ALOGD("android open, url: %s", url);
121 sscanf(url + strlen("android-source:"), "%p", &source);
123 ALOGE("ffmpeg open data source error!");
126 ALOGD("ffmpeg open android data source success, source ptr: %p", source);
128 FFSource *ffs = new FFSource(source);
129 h->priv_data = (void *)ffs;
131 ALOGD("android source open success");
135 static int android_read(URLContext *h, unsigned char *buf, int size)
137 FFSource* ffs = (FFSource *)h->priv_data;
138 return ffs->read(buf, size);
141 static int android_write(URLContext *h, const unsigned char *buf, int size)
146 static int64_t android_seek(URLContext *h, int64_t pos, int whence)
148 FFSource* ffs = (FFSource*)h->priv_data;
150 if (whence == AVSEEK_SIZE) {
151 return ffs->getSize();
158 static int android_close(URLContext *h)
160 FFSource* ffs = (FFSource*)h->priv_data;
161 ALOGD("android source close");
166 static int android_get_handle(URLContext *h)
168 return (intptr_t)h->priv_data;
171 static int android_check(URLContext *h, int mask)
173 FFSource* ffs = (FFSource*)h->priv_data;
175 if (ffs->init_check() < 0)
176 return AVERROR(EACCES); // FIXME
178 return (mask & AVIO_FLAG_READ);
181 static URLProtocol ff_android_protocol;
183 void ffmpeg_register_android_source()
185 memset(&ff_android_protocol, 0, sizeof(URLProtocol));
186 ff_android_protocol.name = "android-source";
187 ff_android_protocol.url_open = android_open;
188 ff_android_protocol.url_read = android_read;
189 ff_android_protocol.url_write = android_write;
190 ff_android_protocol.url_seek = android_seek;
191 ff_android_protocol.url_close = android_close;
192 ff_android_protocol.url_get_file_handle = android_get_handle;
193 ff_android_protocol.url_check = android_check;
195 ffurl_register_protocol(&ff_android_protocol, sizeof(URLProtocol));
198 } // namespace android