/*
- * Unbuffered io for ffmpeg system
+ * unbuffered I/O
* Copyright (c) 2001 Fabrice Bellard
*
* This file is part of Libav.
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-/* needed for usleep() */
-#define _XOPEN_SOURCE 600
#include <unistd.h>
+
#include "libavutil/avstring.h"
#include "libavutil/opt.h"
#include "os_support.h"
#endif
#include "url.h"
-#if FF_API_URL_CLASS
/** @name Logging context. */
/*@{*/
static const char *urlcontext_to_name(void *ptr)
else return "NULL";
}
static const AVOption options[] = {{NULL}};
-static const AVClass urlcontext_class =
- { "URLContext", urlcontext_to_name, options, LIBAVUTIL_VERSION_INT };
+static const AVClass urlcontext_class = {
+ .class_name = "URLContext",
+ .item_name = urlcontext_to_name,
+ .option = options,
+ .version = LIBAVUTIL_VERSION_INT,
+};
/*@}*/
-#endif
static int default_interrupt_cb(void);
URLProtocol *first_protocol = NULL;
-URLInterruptCB *url_interrupt_cb = default_interrupt_cb;
+int (*url_interrupt_cb)(void) = default_interrupt_cb;
+#if FF_API_OLD_AVIO
URLProtocol *av_protocol_next(URLProtocol *p)
{
if(p) return p->next;
else return first_protocol;
}
+#endif
-int av_register_protocol2(URLProtocol *protocol, int size)
+const char *avio_enum_protocols(void **opaque, int output)
+{
+ URLProtocol **p = opaque;
+ *p = *p ? (*p)->next : first_protocol;
+ if (!*p) return NULL;
+ if ((output && (*p)->url_write) || (!output && (*p)->url_read))
+ return (*p)->name;
+ return avio_enum_protocols(opaque, output);
+}
+
+int ffurl_register_protocol(URLProtocol *protocol, int size)
{
URLProtocol **p;
if (size < sizeof(URLProtocol)) {
return 0;
}
-#if FF_API_REGISTER_PROTOCOL
-/* The layout of URLProtocol as of when major was bumped to 52 */
-struct URLProtocol_compat {
- const char *name;
- int (*url_open)(URLContext *h, const char *filename, int flags);
- int (*url_read)(URLContext *h, unsigned char *buf, int size);
- int (*url_write)(URLContext *h, unsigned char *buf, int size);
- int64_t (*url_seek)(URLContext *h, int64_t pos, int whence);
- int (*url_close)(URLContext *h);
- struct URLProtocol *next;
-};
-
-int av_register_protocol(URLProtocol *protocol)
-{
- return av_register_protocol2(protocol, sizeof(struct URLProtocol_compat));
-}
-
-int register_protocol(URLProtocol *protocol)
-{
- return av_register_protocol2(protocol, sizeof(struct URLProtocol_compat));
-}
-#endif
-
static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up,
- const char *filename, int flags)
+ const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
URLContext *uc;
int err;
err = AVERROR(ENOMEM);
goto fail;
}
-#if FF_API_URL_CLASS
uc->av_class = &urlcontext_class;
-#endif
uc->filename = (char *) &uc[1];
strcpy(uc->filename, filename);
uc->prot = up;
av_opt_set_defaults(uc->priv_data);
}
}
+ if (int_cb)
+ uc->interrupt_callback = *int_cb;
*puc = uc;
return 0;
return err;
uc->is_connected = 1;
//We must be careful here as ffurl_seek() could be slow, for example for http
- if( (uc->flags & (URL_WRONLY | URL_RDWR))
+ if( (uc->flags & AVIO_FLAG_WRITE)
|| !strcmp(uc->prot->name, "file"))
if(!uc->is_streamed && ffurl_seek(uc, 0, SEEK_SET) < 0)
uc->is_streamed= 1;
{
int ret;
- ret = url_alloc_for_protocol(puc, up, filename, flags);
+ ret = url_alloc_for_protocol(puc, up, filename, flags, NULL);
if (ret)
goto fail;
ret = ffurl_connect(*puc);
}
int url_alloc(URLContext **puc, const char *filename, int flags)
{
- return ffurl_alloc(puc, filename, flags);
+ return ffurl_alloc(puc, filename, flags, NULL);
}
int url_connect(URLContext* uc)
{
}
int url_open(URLContext **puc, const char *filename, int flags)
{
- return ffurl_open(puc, filename, flags);
+ return ffurl_open(puc, filename, flags, NULL);
}
int url_read(URLContext *h, unsigned char *buf, int size)
{
{
return h->max_packet_size;
}
+void url_get_filename(URLContext *h, char *buf, int buf_size)
+{
+ av_strlcpy(buf, h->filename, buf_size);
+}
+void url_set_interrupt_cb(URLInterruptCB *interrupt_cb)
+{
+ avio_set_interrupt_cb(interrupt_cb);
+}
+int av_register_protocol2(URLProtocol *protocol, int size)
+{
+ return ffurl_register_protocol(protocol, size);
+}
#endif
#define URL_SCHEME_CHARS \
"ABCDEFGHIJKLMNOPQRSTUVWXYZ" \
"0123456789+-."
-int ffurl_alloc(URLContext **puc, const char *filename, int flags)
+int ffurl_alloc(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
URLProtocol *up;
char proto_str[128], proto_nested[128], *ptr;
up = first_protocol;
while (up != NULL) {
if (!strcmp(proto_str, up->name))
- return url_alloc_for_protocol (puc, up, filename, flags);
+ return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME &&
!strcmp(proto_nested, up->name))
- return url_alloc_for_protocol (puc, up, filename, flags);
+ return url_alloc_for_protocol (puc, up, filename, flags, int_cb);
up = up->next;
}
*puc = NULL;
return AVERROR(ENOENT);
}
-int ffurl_open(URLContext **puc, const char *filename, int flags)
+int ffurl_open(URLContext **puc, const char *filename, int flags,
+ const AVIOInterruptCB *int_cb)
{
- int ret = ffurl_alloc(puc, filename, flags);
+ int ret = ffurl_alloc(puc, filename, flags, int_cb);
if (ret)
return ret;
ret = ffurl_connect(*puc);
ret = transfer_func(h, buf+len, size-len);
if (ret == AVERROR(EINTR))
continue;
- if (h->flags & URL_FLAG_NONBLOCK)
+ if (h->flags & AVIO_FLAG_NONBLOCK)
return ret;
if (ret == AVERROR(EAGAIN)) {
ret = 0;
if (ret)
fast_retries = FFMAX(fast_retries, 2);
len += ret;
- if (url_interrupt_cb())
+ if (ff_check_interrupt(&h->interrupt_callback))
return AVERROR_EXIT;
}
return len;
int ffurl_read(URLContext *h, unsigned char *buf, int size)
{
- if (h->flags & URL_WRONLY)
+ if (!(h->flags & AVIO_FLAG_READ))
return AVERROR(EIO);
return retry_transfer_wrapper(h, buf, size, 1, h->prot->url_read);
}
int ffurl_read_complete(URLContext *h, unsigned char *buf, int size)
{
- if (h->flags & URL_WRONLY)
+ if (!(h->flags & AVIO_FLAG_READ))
return AVERROR(EIO);
return retry_transfer_wrapper(h, buf, size, size, h->prot->url_read);
}
int ffurl_write(URLContext *h, const unsigned char *buf, int size)
{
- if (!(h->flags & (URL_WRONLY | URL_RDWR)))
+ if (!(h->flags & AVIO_FLAG_WRITE))
return AVERROR(EIO);
/* avoid sending too big packets */
if (h->max_packet_size && size > h->max_packet_size)
#if CONFIG_NETWORK
ff_network_close();
#endif
- if (h->prot->priv_data_size)
+ if (h->prot->priv_data_size) {
+ if (h->prot->priv_data_class)
+ av_opt_free(h->priv_data);
av_free(h->priv_data);
+ }
av_free(h);
return ret;
}
+#if FF_API_OLD_AVIO
int url_exist(const char *filename)
{
URLContext *h;
- if (ffurl_open(&h, filename, URL_RDONLY) < 0)
+ if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL) < 0)
return 0;
ffurl_close(h);
return 1;
}
+#endif
+
+int avio_check(const char *url, int flags)
+{
+ URLContext *h;
+ int ret = ffurl_alloc(&h, url, flags, NULL);
+ if (ret)
+ return ret;
+
+ if (h->prot->url_check) {
+ ret = h->prot->url_check(h, flags);
+ } else {
+ ret = ffurl_connect(h);
+ if (ret >= 0)
+ ret = flags;
+ }
+
+ ffurl_close(h);
+ return ret;
+}
int64_t ffurl_size(URLContext *h)
{
return h->prot->url_get_file_handle(h);
}
-void url_get_filename(URLContext *h, char *buf, int buf_size)
-{
- av_strlcpy(buf, h->filename, buf_size);
-}
-
-
static int default_interrupt_cb(void)
{
return 0;
}
-void url_set_interrupt_cb(URLInterruptCB *interrupt_cb)
+void avio_set_interrupt_cb(int (*interrupt_cb)(void))
{
if (!interrupt_cb)
interrupt_cb = default_interrupt_cb;
url_interrupt_cb = interrupt_cb;
}
+int ff_check_interrupt(AVIOInterruptCB *cb)
+{
+ int ret;
+ if (cb && cb->callback && (ret = cb->callback(cb->opaque)))
+ return ret;
+ return url_interrupt_cb();
+}
+
+#if FF_API_OLD_AVIO
int av_url_read_pause(URLContext *h, int pause)
{
if (!h->prot->url_read_pause)
return AVERROR(ENOSYS);
return h->prot->url_read_seek(h, stream_index, timestamp, flags);
}
+#endif