34
static URLProtocol *first_protocol = NULL;
36
URLProtocol *ffurl_protocol_next(URLProtocol *prev)
38
return prev ? prev->next : first_protocol;
33
41
/** @name Logging context. */
35
43
static const char *urlcontext_to_name(void *ptr)
38
46
if(h->prot) return h->prot->name;
39
47
else return "NULL";
50
static void *urlcontext_child_next(void *obj, void *prev)
53
if (!prev && h->priv_data && h->prot->priv_data_class)
58
static const AVClass *urlcontext_child_class_next(const AVClass *prev)
60
URLProtocol *p = NULL;
62
/* find the protocol that corresponds to prev */
63
while (prev && (p = ffurl_protocol_next(p)))
64
if (p->priv_data_class == prev)
67
/* find next protocol with priv options */
68
while (p = ffurl_protocol_next(p))
69
if (p->priv_data_class)
70
return p->priv_data_class;
41
75
static const AVOption options[] = {{NULL}};
42
static const AVClass urlcontext_class = {
76
const AVClass ffurl_context_class = {
43
77
.class_name = "URLContext",
44
78
.item_name = urlcontext_to_name,
46
80
.version = LIBAVUTIL_VERSION_INT,
81
.child_next = urlcontext_child_next,
82
.child_class_next = urlcontext_child_class_next,
87
#if FF_API_OLD_INTERRUPT_CB
50
88
static int default_interrupt_cb(void);
52
URLProtocol *first_protocol = NULL;
53
89
int (*url_interrupt_cb)(void) = default_interrupt_cb;
55
92
#if FF_API_OLD_AVIO
56
93
URLProtocol *av_protocol_next(URLProtocol *p)
59
else return first_protocol;
95
return ffurl_protocol_next(p);
63
99
const char *avio_enum_protocols(void **opaque, int output)
65
101
URLProtocol **p = opaque;
66
*p = *p ? (*p)->next : first_protocol;
102
*p = ffurl_protocol_next(*p);
67
103
if (!*p) return NULL;
68
104
if ((output && (*p)->url_write) || (!output && (*p)->url_read))
69
105
return (*p)->name;
88
124
static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
89
const char *filename, int flags)
125
const char *filename, int flags,
126
const AVIOInterruptCB *int_cb)
94
131
#if CONFIG_NETWORK
95
if (!ff_network_init())
132
if (up->flags & URL_PROTOCOL_FLAG_NETWORK && !ff_network_init())
96
133
return AVERROR(EIO);
98
135
uc = av_mallocz(sizeof(URLContext) + strlen(filename) + 1);
100
137
err = AVERROR(ENOMEM);
103
uc->av_class = &urlcontext_class;
140
uc->av_class = &ffurl_context_class;
104
141
uc->filename = (char *) &uc[1];
105
142
strcpy(uc->filename, filename);
114
151
av_opt_set_defaults(uc->priv_data);
155
uc->interrupt_callback = *int_cb;
122
161
#if CONFIG_NETWORK
162
if (up->flags & URL_PROTOCOL_FLAG_NETWORK)
128
int ffurl_connect(URLContext* uc)
168
int ffurl_connect(URLContext* uc, AVDictionary **options)
130
int err = uc->prot->url_open(uc, uc->filename, uc->flags);
172
uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) :
174
uc->prot->url_open(uc, uc->filename, uc->flags);
133
177
uc->is_connected = 1;
148
ret = url_alloc_for_protocol(puc, up, filename, flags);
192
ret = url_alloc_for_protocol(puc, up, filename, flags, NULL);
151
ret = ffurl_connect(*puc);
195
ret = ffurl_connect(*puc, NULL);
159
203
int url_alloc(URLContext **puc, const char *filename, int flags)
161
return ffurl_alloc(puc, filename, flags);
205
return ffurl_alloc(puc, filename, flags, NULL);
163
207
int url_connect(URLContext* uc)
165
return ffurl_connect(uc);
209
return ffurl_connect(uc, NULL);
167
211
int url_open(URLContext **puc, const char *filename, int flags)
169
return ffurl_open(puc, filename, flags);
213
return ffurl_open(puc, filename, flags, NULL, NULL);
171
215
int url_read(URLContext *h, unsigned char *buf, int size)
219
263
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
222
int ffurl_alloc(URLContext **puc, const char *filename, int flags)
266
int ffurl_alloc(URLContext **puc, const char *filename, int flags,
267
const AVIOInterruptCB *int_cb)
269
URLProtocol *up = NULL;
225
270
char proto_str[128], proto_nested[128], *ptr;
226
271
size_t proto_len = strspn(filename, URL_SCHEME_CHARS);
234
279
if ((ptr = strchr(proto_nested, '+')))
282
while (up = ffurl_protocol_next(up)) {
239
283
if (!strcmp(proto_str, up->name))
240
return url_alloc_for_protocol (puc, up, filename, flags);
284
return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
241
285
if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
242
286
!strcmp(proto_nested, up->name))
243
return url_alloc_for_protocol (puc, up, filename, flags);
287
return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
247
290
return AVERROR(ENOENT);
250
int ffurl_open(URLContext **puc, const char *filename, int flags)
293
int ffurl_open(URLContext **puc, const char *filename, int flags,
294
const AVIOInterruptCB *int_cb, AVDictionary **options)
252
int ret = ffurl_alloc(puc, filename, flags);
296
int ret = ffurl_alloc(puc, filename, flags, int_cb);
255
ret = ffurl_connect(*puc);
299
if (options && (*puc)->prot->priv_data_class &&
300
(ret = av_opt_set_dict((*puc)->priv_data, options)) < 0)
302
ret = ffurl_connect(*puc, options);
258
306
ffurl_close(*puc);
333
381
if (h->is_connected && h->prot->url_close)
334
382
ret = h->prot->url_close(h);
335
383
#if CONFIG_NETWORK
384
if (h->prot->flags & URL_PROTOCOL_FLAG_NETWORK)
338
if (h->prot->priv_data_size)
387
if (h->prot->priv_data_size) {
388
if (h->prot->priv_data_class)
389
av_opt_free(h->priv_data);
339
390
av_free(h->priv_data);
345
397
int url_exist(const char *filename)
348
if (ffurl_open(&h, filename, AVIO_FLAG_READ) < 0)
400
if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL, NULL) < 0)
355
407
int avio_check(const char *url, int flags)
358
int ret = ffurl_alloc(&h, url, flags);
410
int ret = ffurl_alloc(&h, url, flags, NULL);
362
414
if (h->prot->url_check) {
363
415
ret = h->prot->url_check(h, flags);
365
ret = ffurl_connect(h);
417
ret = ffurl_connect(h, NULL);
404
457
interrupt_cb = default_interrupt_cb;
405
458
url_interrupt_cb = interrupt_cb;
462
int ff_check_interrupt(AVIOInterruptCB *cb)
465
if (cb && cb->callback && (ret = cb->callback(cb->opaque)))
467
#if FF_API_OLD_INTERRUPT_CB
468
return url_interrupt_cb();
408
474
#if FF_API_OLD_AVIO
409
475
int av_url_read_pause(URLContext *h, int pause)