• Home
  • History
  • Annotate
  • Line#
  • Navigate
  • Raw
  • Download
  • only in /asuswrt-rt-n18u-9.0.0.4.380.2695/release/src-rt-6.x.4708/router/ffmpeg/libavformat/
1/*
2 * Unbuffered io for ffmpeg system
3 * Copyright (c) 2001 Fabrice Bellard
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22/* needed for usleep() */
23#define _XOPEN_SOURCE 600
24#include <unistd.h>
25#include "libavutil/avstring.h"
26#include "libavcodec/opt.h"
27#include "os_support.h"
28#include "avformat.h"
29#if CONFIG_NETWORK
30#include "network.h"
31#endif
32
33#if LIBAVFORMAT_VERSION_MAJOR >= 53
34/** @name Logging context. */
35/*@{*/
36static const char *urlcontext_to_name(void *ptr)
37{
38    URLContext *h = (URLContext *)ptr;
39    if(h->prot) return h->prot->name;
40    else        return "NULL";
41}
42static const AVOption options[] = {{NULL}};
43static const AVClass urlcontext_class =
44        { "URLContext", urlcontext_to_name, options, LIBAVUTIL_VERSION_INT };
45/*@}*/
46#endif
47
48static int default_interrupt_cb(void);
49
50URLProtocol *first_protocol = NULL;
51URLInterruptCB *url_interrupt_cb = default_interrupt_cb;
52
53URLProtocol *av_protocol_next(URLProtocol *p)
54{
55    if(p) return p->next;
56    else  return first_protocol;
57}
58
59int av_register_protocol(URLProtocol *protocol)
60{
61    URLProtocol **p;
62    p = &first_protocol;
63    while (*p != NULL) p = &(*p)->next;
64    *p = protocol;
65    protocol->next = NULL;
66    return 0;
67}
68
69#if LIBAVFORMAT_VERSION_MAJOR < 53
70int register_protocol(URLProtocol *protocol)
71{
72    return av_register_protocol(protocol);
73}
74#endif
75
76int url_open_protocol (URLContext **puc, struct URLProtocol *up,
77                       const char *filename, int flags)
78{
79    URLContext *uc;
80    int err;
81
82#if CONFIG_NETWORK
83    if (!ff_network_init())
84        return AVERROR(EIO);
85#endif
86    uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
87    if (!uc) {
88        err = AVERROR(ENOMEM);
89        goto fail;
90    }
91#if LIBAVFORMAT_VERSION_MAJOR >= 53
92    uc->av_class = &urlcontext_class;
93#endif
94    uc->filename = (char *) &uc[1];
95    strcpy(uc->filename, filename);
96    uc->prot = up;
97    uc->flags = flags;
98    uc->is_streamed = 0; /* default = not streamed */
99    uc->max_packet_size = 0; /* default: stream file */
100    err = up->url_open(uc, filename, flags);
101    if (err < 0) {
102        av_free(uc);
103        goto fail;
104    }
105
106    //We must be careful here as url_seek() could be slow, for example for http
107    if(   (flags & (URL_WRONLY | URL_RDWR))
108       || !strcmp(up->name, "file"))
109        if(!uc->is_streamed && url_seek(uc, 0, SEEK_SET) < 0)
110            uc->is_streamed= 1;
111    *puc = uc;
112    return 0;
113 fail:
114    *puc = NULL;
115#if CONFIG_NETWORK
116    ff_network_close();
117#endif
118    return err;
119}
120
121int url_open(URLContext **puc, const char *filename, int flags)
122{
123    URLProtocol *up;
124    const char *p;
125    char proto_str[128], *q;
126
127    p = filename;
128    q = proto_str;
129    while (*p != '\0' && *p != ':') {
130        /* protocols can only contain alphabetic chars */
131        if (!isalpha(*p))
132            goto file_proto;
133        if ((q - proto_str) < sizeof(proto_str) - 1)
134            *q++ = *p;
135        p++;
136    }
137    /* if the protocol has length 1, we consider it is a dos drive */
138    if (*p == '\0' || is_dos_path(filename)) {
139    file_proto:
140        strcpy(proto_str, "file");
141    } else {
142        *q = '\0';
143    }
144
145    up = first_protocol;
146    while (up != NULL) {
147        if (!strcmp(proto_str, up->name))
148            return url_open_protocol (puc, up, filename, flags);
149        up = up->next;
150    }
151    *puc = NULL;
152    return AVERROR(ENOENT);
153}
154
155int url_read(URLContext *h, unsigned char *buf, int size)
156{
157    int ret;
158    if (h->flags & URL_WRONLY)
159        return AVERROR(EIO);
160    ret = h->prot->url_read(h, buf, size);
161    return ret;
162}
163
164int url_read_complete(URLContext *h, unsigned char *buf, int size)
165{
166    int ret, len;
167    int fast_retries = 5;
168
169    len = 0;
170    while (len < size) {
171        ret = url_read(h, buf+len, size-len);
172        if (ret == AVERROR(EAGAIN)) {
173            ret = 0;
174            if (fast_retries)
175                fast_retries--;
176            else
177                usleep(1000);
178        } else if (ret < 1)
179            return ret < 0 ? ret : len;
180        if (ret)
181           fast_retries = FFMAX(fast_retries, 2);
182        len += ret;
183    }
184    return len;
185}
186
187int url_write(URLContext *h, unsigned char *buf, int size)
188{
189    int ret;
190    if (!(h->flags & (URL_WRONLY | URL_RDWR)))
191        return AVERROR(EIO);
192    /* avoid sending too big packets */
193    if (h->max_packet_size && size > h->max_packet_size)
194        return AVERROR(EIO);
195    ret = h->prot->url_write(h, buf, size);
196    return ret;
197}
198
199int64_t url_seek(URLContext *h, int64_t pos, int whence)
200{
201    int64_t ret;
202
203    if (!h->prot->url_seek)
204        return AVERROR(ENOSYS);
205    ret = h->prot->url_seek(h, pos, whence & ~AVSEEK_FORCE);
206    return ret;
207}
208
209int url_close(URLContext *h)
210{
211    int ret = 0;
212    if (!h) return 0; /* can happen when url_open fails */
213
214    if (h->prot->url_close)
215        ret = h->prot->url_close(h);
216#if CONFIG_NETWORK
217    ff_network_close();
218#endif
219    av_free(h);
220    return ret;
221}
222
223int url_exist(const char *filename)
224{
225    URLContext *h;
226    if (url_open(&h, filename, URL_RDONLY) < 0)
227        return 0;
228    url_close(h);
229    return 1;
230}
231
232int64_t url_filesize(URLContext *h)
233{
234    int64_t pos, size;
235
236    size= url_seek(h, 0, AVSEEK_SIZE);
237    if(size<0){
238        pos = url_seek(h, 0, SEEK_CUR);
239        if ((size = url_seek(h, -1, SEEK_END)) < 0)
240            return size;
241        size++;
242        url_seek(h, pos, SEEK_SET);
243    }
244    return size;
245}
246
247int url_get_file_handle(URLContext *h)
248{
249    if (!h->prot->url_get_file_handle)
250        return -1;
251    return h->prot->url_get_file_handle(h);
252}
253
254int url_get_max_packet_size(URLContext *h)
255{
256    return h->max_packet_size;
257}
258
259void url_get_filename(URLContext *h, char *buf, int buf_size)
260{
261    av_strlcpy(buf, h->filename, buf_size);
262}
263
264
265static int default_interrupt_cb(void)
266{
267    return 0;
268}
269
270void url_set_interrupt_cb(URLInterruptCB *interrupt_cb)
271{
272    if (!interrupt_cb)
273        interrupt_cb = default_interrupt_cb;
274    url_interrupt_cb = interrupt_cb;
275}
276
277int av_url_read_pause(URLContext *h, int pause)
278{
279    if (!h->prot->url_read_pause)
280        return AVERROR(ENOSYS);
281    return h->prot->url_read_pause(h, pause);
282}
283
284int64_t av_url_read_seek(URLContext *h,
285        int stream_index, int64_t timestamp, int flags)
286{
287    if (!h->prot->url_read_seek)
288        return AVERROR(ENOSYS);
289    return h->prot->url_read_seek(h, stream_index, timestamp, flags);
290}
291