diff options
author | Michael Niedermayer <michaelni@gmx.at> | 2011-11-13 23:43:12 +0100 |
---|---|---|
committer | Michael Niedermayer <michaelni@gmx.at> | 2011-11-14 00:33:39 +0100 |
commit | 5f268ca5c57f3ad3050b58f513651c17304d3653 (patch) | |
tree | f66ad7e5c4fd5656db9a95218f2ad433a982d81b /libavformat | |
parent | 4fa6e9d0b40653010b35278f7e8b556958341205 (diff) | |
parent | 32caa7b13cecca59213c73fa94dd683c2b003bfd (diff) | |
download | ffmpeg-5f268ca5c57f3ad3050b58f513651c17304d3653.tar.gz |
Merge remote-tracking branch 'qatar/master'
* qatar/master:
lavf: pass options from AVFormatContext to avio.
avformat: Use avio_open2, pass the AVFormatContext interrupt_callback onwards
avio: add avio_open2, taking an interrupt callback and options
avio: add support for passing options to protocols.
avio: add and use ffurl_protocol_next().
avformat: Pass the interrupt callback on to chained muxers/demuxers
avio: Add an AVIOInterruptCB parameter to ffurl_open/ffurl_alloc
avformat: Use ff_check_interrupt
avio: Add an internal utility function for checking the new interrupt callback
avio: Add AVIOInterruptCB
texi2html: remove stray \n
doc: prettyfy the texi2html documentation
swscale: handle unaligned buffers in yuv2plane1
Conflicts:
libavformat/avformat.h
libavformat/avio.c
libavformat/mov.c
Merged-by: Michael Niedermayer <michaelni@gmx.at>
Diffstat (limited to 'libavformat')
-rw-r--r-- | libavformat/applehttp.c | 19 | ||||
-rw-r--r-- | libavformat/applehttpproto.c | 10 | ||||
-rw-r--r-- | libavformat/avformat.h | 12 | ||||
-rw-r--r-- | libavformat/avio.c | 117 | ||||
-rw-r--r-- | libavformat/avio.h | 53 | ||||
-rw-r--r-- | libavformat/avio_internal.h | 4 | ||||
-rw-r--r-- | libavformat/aviobuf.c | 39 | ||||
-rw-r--r-- | libavformat/cache.c | 2 | ||||
-rw-r--r-- | libavformat/concat.c | 3 | ||||
-rw-r--r-- | libavformat/crypto.c | 3 | ||||
-rw-r--r-- | libavformat/gopher.c | 3 | ||||
-rw-r--r-- | libavformat/http.c | 3 | ||||
-rw-r--r-- | libavformat/img2.c | 6 | ||||
-rw-r--r-- | libavformat/md5proto.c | 3 | ||||
-rw-r--r-- | libavformat/mmsh.c | 10 | ||||
-rw-r--r-- | libavformat/mmst.c | 3 | ||||
-rw-r--r-- | libavformat/mov.c | 7 | ||||
-rw-r--r-- | libavformat/options.c | 27 | ||||
-rw-r--r-- | libavformat/rtmpproto.c | 3 | ||||
-rw-r--r-- | libavformat/rtpenc_chain.c | 2 | ||||
-rw-r--r-- | libavformat/rtpproto.c | 6 | ||||
-rw-r--r-- | libavformat/rtsp.c | 27 | ||||
-rw-r--r-- | libavformat/sapdec.c | 4 | ||||
-rw-r--r-- | libavformat/sapenc.c | 5 | ||||
-rw-r--r-- | libavformat/tcp.c | 4 | ||||
-rw-r--r-- | libavformat/tls.c | 5 | ||||
-rw-r--r-- | libavformat/url.h | 45 | ||||
-rw-r--r-- | libavformat/utils.c | 9 |
28 files changed, 341 insertions, 93 deletions
diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index 432bf4ebcc..97bd74a152 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -99,6 +99,7 @@ typedef struct AppleHTTPContext { int cur_seq_no; int end_of_segment; int first_packet; + AVIOInterruptCB *interrupt_callback; } AppleHTTPContext; static int read_chomp_line(AVIOContext *s, char *buf, int maxlen) @@ -209,7 +210,8 @@ static int parse_playlist(AppleHTTPContext *c, const char *url, if (!in) { close_in = 1; - if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open2(&in, url, AVIO_FLAG_READ, + c->interrupt_callback, NULL)) < 0) return ret; } @@ -322,13 +324,15 @@ static int open_input(struct variant *var) { struct segment *seg = var->segments[var->cur_seq_no - var->start_seq_no]; if (seg->key_type == KEY_NONE) { - return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ); + return ffurl_open(&var->input, seg->url, AVIO_FLAG_READ, + &var->parent->interrupt_callback, NULL); } else if (seg->key_type == KEY_AES_128) { char iv[33], key[33], url[MAX_URL_SIZE]; int ret; if (strcmp(seg->key, var->key_url)) { URLContext *uc; - if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ) == 0) { + if (ffurl_open(&uc, seg->key, AVIO_FLAG_READ, + &var->parent->interrupt_callback, NULL) == 0) { if (ffurl_read_complete(uc, var->key, sizeof(var->key)) != sizeof(var->key)) { av_log(NULL, AV_LOG_ERROR, "Unable to read key file %s\n", @@ -348,11 +352,12 @@ static int open_input(struct variant *var) snprintf(url, sizeof(url), "crypto+%s", seg->url); else snprintf(url, sizeof(url), "crypto:%s", seg->url); - if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ)) < 0) + if ((ret = ffurl_alloc(&var->input, url, AVIO_FLAG_READ, + &var->parent->interrupt_callback)) < 0) return ret; av_opt_set(var->input->priv_data, "key", key, 0); av_opt_set(var->input->priv_data, "iv", iv, 0); - if ((ret = ffurl_connect(var->input)) < 0) { + if ((ret = ffurl_connect(var->input, NULL)) < 0) { ffurl_close(var->input); var->input = NULL; return ret; @@ -388,7 +393,7 @@ reload: return AVERROR_EOF; while (av_gettime() - v->last_load_time < v->target_duration*1000000) { - if (url_interrupt_cb()) + if (ff_check_interrupt(c->interrupt_callback)) return AVERROR_EXIT; usleep(100*1000); } @@ -433,6 +438,8 @@ static int applehttp_read_header(AVFormatContext *s, AVFormatParameters *ap) AppleHTTPContext *c = s->priv_data; int ret = 0, i, j, stream_offset = 0; + c->interrupt_callback = &s->interrupt_callback; + if ((ret = parse_playlist(c, s->filename, NULL, s->pb)) < 0) goto fail; diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c index bb5029d82f..8218c0e05f 100644 --- a/libavformat/applehttpproto.c +++ b/libavformat/applehttpproto.c @@ -114,7 +114,8 @@ static int parse_playlist(URLContext *h, const char *url) char line[1024]; const char *ptr; - if ((ret = avio_open(&in, url, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open2(&in, url, AVIO_FLAG_READ, + &h->interrupt_callback, NULL)) < 0) return ret; read_chomp_line(in, line, sizeof(line)); @@ -266,7 +267,7 @@ retry: if (s->finished) return AVERROR_EOF; while (av_gettime() - s->last_load_time < s->target_duration*1000000) { - if (url_interrupt_cb()) + if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; usleep(100*1000); } @@ -274,9 +275,10 @@ retry: } url = s->segments[s->cur_seq_no - s->start_seq_no]->url, av_log(h, AV_LOG_DEBUG, "opening %s\n", url); - ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ); + ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ, + &h->interrupt_callback, NULL); if (ret < 0) { - if (url_interrupt_cb()) + if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; av_log(h, AV_LOG_WARNING, "Unable to open %s\n", url); s->cur_seq_no++; diff --git a/libavformat/avformat.h b/libavformat/avformat.h index cf0dae9c32..e0e9c1f734 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -1028,11 +1028,23 @@ typedef struct AVFormatContext { int error_recognition; /** + * Custom interrupt callbacks for the I/O layer. + * + * decoding: set by the user before avformat_open_input(). + * encoding: set by the user before avformat_write_header() + * (mainly useful for AVFMT_NOFILE formats). The callback + * should also be passed to avio_open2() if it's used to + * open the file. + */ + AVIOInterruptCB interrupt_callback; + + /** * Transport stream id. * This will be moved into demuxer private options. Thus no API/ABI compatibility */ int ts_id; + /***************************************************************** * All fields below this line are not part of the public API. They * may not be used outside of libavformat and can be changed and diff --git a/libavformat/avio.c b/libavformat/avio.c index 4141d0bd7d..879844aefc 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -22,6 +22,7 @@ #include <unistd.h> #include "libavutil/avstring.h" +#include "libavutil/dict.h" #include "libavutil/opt.h" #include "os_support.h" #include "avformat.h" @@ -30,6 +31,13 @@ #endif #include "url.h" +static URLProtocol *first_protocol = NULL; + +URLProtocol *ffurl_protocol_next(URLProtocol *prev) +{ + return prev ? prev->next : first_protocol; +} + /** @name Logging context. */ /*@{*/ static const char *urlcontext_to_name(void *ptr) @@ -38,33 +46,59 @@ static const char *urlcontext_to_name(void *ptr) if(h->prot) return h->prot->name; else return "NULL"; } + +static void *urlcontext_child_next(void *obj, void *prev) +{ + URLContext *h = obj; + if (!prev && h->priv_data && h->prot->priv_data_class) + return h->priv_data; + return NULL; +} + +static const AVClass *urlcontext_child_class_next(const AVClass *prev) +{ + URLProtocol *p = NULL; + + /* find the protocol that corresponds to prev */ + while (prev && (p = ffurl_protocol_next(p))) + if (p->priv_data_class == prev) + break; + + /* find next protocol with priv options */ + while (p = ffurl_protocol_next(p)) + if (p->priv_data_class) + return p->priv_data_class; + return NULL; + +} + static const AVOption options[] = {{NULL}}; -static const AVClass urlcontext_class = { +const AVClass ffurl_context_class = { .class_name = "URLContext", .item_name = urlcontext_to_name, .option = options, .version = LIBAVUTIL_VERSION_INT, + .child_next = urlcontext_child_next, + .child_class_next = urlcontext_child_class_next, }; /*@}*/ static int default_interrupt_cb(void); -URLProtocol *first_protocol = NULL; int (*url_interrupt_cb)(void) = default_interrupt_cb; URLProtocol *av_protocol_next(URLProtocol *p) { - if(p) return p->next; - else return first_protocol; + return ffurl_protocol_next(p); } 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; + URLProtocol **p = opaque; + *p = ffurl_protocol_next(*p); + if (!*p) return NULL; + if ((output && (*p)->url_write) || (!output && (*p)->url_read)) + return (*p)->name; return avio_enum_protocols(opaque, output); } @@ -84,7 +118,8 @@ int ffurl_register_protocol(URLProtocol *protocol, int size) } 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; @@ -98,7 +133,7 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, err = AVERROR(ENOMEM); goto fail; } - uc->av_class = &urlcontext_class; + uc->av_class = &ffurl_context_class; uc->filename = (char *) &uc[1]; strcpy(uc->filename, filename); uc->prot = up; @@ -112,6 +147,8 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, av_opt_set_defaults(uc->priv_data); } } + if (int_cb) + uc->interrupt_callback = *int_cb; *puc = uc; return 0; @@ -123,9 +160,13 @@ static int url_alloc_for_protocol (URLContext **puc, struct URLProtocol *up, return err; } -int ffurl_connect(URLContext* uc) +int ffurl_connect(URLContext* uc, AVDictionary **options) { - int err = uc->prot->url_open(uc, uc->filename, uc->flags); + int err = +#if !FF_API_OLD_AVIO + uc->prot->url_open2 ? uc->prot->url_open2(uc, uc->filename, uc->flags, options) : +#endif + uc->prot->url_open(uc, uc->filename, uc->flags); if (err) return err; uc->is_connected = 1; @@ -143,10 +184,10 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up, { 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); + ret = ffurl_connect(*puc, NULL); if (!ret) return 0; fail: @@ -156,15 +197,15 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up, } 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) { - return ffurl_connect(uc); + return ffurl_connect(uc, NULL); } int url_open(URLContext **puc, const char *filename, int flags) { - return ffurl_open(puc, filename, flags); + return ffurl_open(puc, filename, flags, NULL, NULL); } int url_read(URLContext *h, unsigned char *buf, int size) { @@ -217,9 +258,10 @@ int av_register_protocol2(URLProtocol *protocol, int size) "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; + URLProtocol *up = NULL; char proto_str[128], proto_nested[128], *ptr; size_t proto_len = strspn(filename, URL_SCHEME_CHARS); @@ -237,27 +279,30 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags) if ((ptr = strchr(proto_nested, '+'))) *ptr = '\0'; - up = first_protocol; - while (up != NULL) { + while (up = ffurl_protocol_next(up)) { 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); - up = up->next; + return url_alloc_for_protocol (puc, up, filename, flags, int_cb); } *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, AVDictionary **options) { - int ret = ffurl_alloc(puc, filename, flags); + int ret = ffurl_alloc(puc, filename, flags, int_cb); if (ret) return ret; - ret = ffurl_connect(*puc); + if (options && (*puc)->prot->priv_data_class && + (ret = av_opt_set_dict((*puc)->priv_data, options)) < 0) + goto fail; + ret = ffurl_connect(*puc, options); if (!ret) return 0; +fail: ffurl_close(*puc); *puc = NULL; return ret; @@ -287,7 +332,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int if (ret) fast_retries = FFMAX(fast_retries, 2); len += ret; - if (len < size && url_interrupt_cb()) + if (len < size && ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; } return len; @@ -351,7 +396,7 @@ int ffurl_close(URLContext *h) int url_exist(const char *filename) { URLContext *h; - if (ffurl_open(&h, filename, AVIO_FLAG_READ) < 0) + if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL, NULL) < 0) return 0; ffurl_close(h); return 1; @@ -361,14 +406,14 @@ int url_exist(const char *filename) int avio_check(const char *url, int flags) { URLContext *h; - int ret = ffurl_alloc(&h, url, flags); + 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); + ret = ffurl_connect(h, NULL); if (ret >= 0) ret = flags; } @@ -411,6 +456,14 @@ void avio_set_interrupt_cb(int (*interrupt_cb)(void)) 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) { diff --git a/libavformat/avio.h b/libavformat/avio.h index 8210cbd1da..14f3b7b292 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -28,6 +28,7 @@ #include <stdint.h> #include "libavutil/common.h" +#include "libavutil/dict.h" #include "libavutil/log.h" #include "libavformat/version.h" @@ -36,6 +37,22 @@ #define AVIO_SEEKABLE_NORMAL 0x0001 /**< Seeking works like for a local file */ /** + * Callback for checking whether to abort blocking functions. + * AVERROR_EXIT is returned in this case by the interrupted + * function. During blocking operations, callback is called with + * opaque as parameter. If the callback returns 1, the + * blocking operation will be aborted. + * + * No members can be added to this struct without a major bump, if + * new elements have been added after this struct in AVFormatContext + * or AVIOContext. + */ +typedef struct { + int (*callback)(void*); + void *opaque; +} AVIOInterruptCB; + +/** * Bytestream IO Context. * New fields can be added to the end with minor version bumps. * Removal, reordering and changes to existing fields require a major @@ -48,6 +65,21 @@ * function pointers specified in avio_alloc_context() */ typedef struct { +#if !FF_API_OLD_AVIO + /** + * A class for private options. + * + * If this AVIOContext is created by avio_open2(), av_class is set and + * passes the options down to protocols. + * + * If this AVIOContext is manually allocated, then av_class may be set by + * the caller. + * + * warning -- this field can be NULL, be sure to not pass this AVIOContext + * to any av_opt_* functions in that case. + */ + AVClass *av_class; +#endif unsigned char *buffer; /**< Start of the buffer. */ int buffer_size; /**< Maximum buffer size */ unsigned char *buf_ptr; /**< Current position in the buffer */ @@ -109,6 +141,7 @@ typedef struct URLContext { void *priv_data; char *filename; /**< specified URL */ int is_connected; + AVIOInterruptCB interrupt_callback; } URLContext; #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ @@ -557,6 +590,26 @@ int avio_get_str16be(AVIOContext *pb, int maxlen, char *buf, int buflen); int avio_open(AVIOContext **s, const char *url, int flags); /** + * Create and initialize a AVIOContext for accessing the + * resource indicated by url. + * @note When the resource indicated by url has been opened in + * read+write mode, the AVIOContext can be used only for writing. + * + * @param s Used to return the pointer to the created AVIOContext. + * In case of failure the pointed to value is set to NULL. + * @param flags flags which control how the resource indicated by url + * is to be opened + * @param int_cb an interrupt callback to be used at the protocols level + * @param options A dictionary filled with protocol-private options. On return + * this parameter will be destroyed and replaced with a dict containing options + * that were not found. May be NULL. + * @return 0 in case of success, a negative value corresponding to an + * AVERROR code in case of failure + */ +int avio_open2(AVIOContext **s, const char *url, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options); + +/** * Close the resource accessed by the AVIOContext s and free it. * This function can only be used if s was opened by avio_open(). * diff --git a/libavformat/avio_internal.h b/libavformat/avio_internal.h index 4c80163d31..f140897c5d 100644 --- a/libavformat/avio_internal.h +++ b/libavformat/avio_internal.h @@ -23,6 +23,10 @@ #include "avio.h" #include "url.h" +#include "libavutil/log.h" + +extern const AVClass ffio_url_class; + int ffio_init_context(AVIOContext *s, unsigned char *buffer, int buffer_size, diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 91a91db630..d9d012ee90 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -20,7 +20,10 @@ */ #include "libavutil/crc.h" +#include "libavutil/dict.h" #include "libavutil/intreadwrite.h" +#include "libavutil/log.h" +#include "libavutil/opt.h" #include "avformat.h" #include "avio.h" #include "avio_internal.h" @@ -37,6 +40,31 @@ */ #define SHORT_SEEK_THRESHOLD 4096 +#if !FF_API_OLD_AVIO +static void *ffio_url_child_next(void *obj, void *prev) +{ + AVIOContext *s = obj; + return prev ? NULL : s->opaque; +} + +static const AVClass *ffio_url_child_class_next(const AVClass *prev) +{ + return prev ? NULL : &ffurl_context_class; +} + +static const AVOption ffio_url_options[] = { + { NULL }, +}; + +const AVClass ffio_url_class = { + .class_name = "AVIOContext", + .item_name = av_default_item_name, + .version = LIBAVUTIL_VERSION_INT, + .option = ffio_url_options, + .child_next = ffio_url_child_next, + .child_class_next = ffio_url_child_class_next, +}; +#endif static void fill_buffer(AVIOContext *s); static int url_resetbuf(AVIOContext *s, int flags); @@ -866,6 +894,9 @@ int ffio_fdopen(AVIOContext **s, URLContext *h) (*s)->read_pause = (int (*)(void *, int))h->prot->url_read_pause; (*s)->read_seek = (int64_t (*)(void *, int, int64_t, int))h->prot->url_read_seek; } +#if !FF_API_OLD_AVIO + (*s)->av_class = &ffio_url_class; +#endif return 0; } @@ -939,10 +970,16 @@ int ffio_rewind_with_probe_data(AVIOContext *s, unsigned char *buf, int buf_size int avio_open(AVIOContext **s, const char *filename, int flags) { + return avio_open2(s, filename, flags, NULL, NULL); +} + +int avio_open2(AVIOContext **s, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options) +{ URLContext *h; int err; - err = ffurl_open(&h, filename, flags); + err = ffurl_open(&h, filename, flags, int_cb, options); if (err < 0) return err; err = ffio_fdopen(s, h); diff --git a/libavformat/cache.c b/libavformat/cache.c index 74f008e0d1..c2bddf5f6d 100644 --- a/libavformat/cache.c +++ b/libavformat/cache.c @@ -72,7 +72,7 @@ static int cache_open(URLContext *h, const char *arg, int flags) unlink(buffername); av_free(buffername); - return ffurl_open(&c->inner, arg, flags); + return ffurl_open(&c->inner, arg, flags, &h->interrupt_callback, NULL); } static int cache_read(URLContext *h, unsigned char *buf, int size) diff --git a/libavformat/concat.c b/libavformat/concat.c index ba1b6a544a..81f37383b9 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -101,7 +101,8 @@ static av_cold int concat_open(URLContext *h, const char *uri, int flags) uri += len + strspn(uri+len, AV_CAT_SEPARATOR); /* creating URLContext */ - if ((err = ffurl_open(&uc, node_uri, flags)) < 0) + if ((err = ffurl_open(&uc, node_uri, flags, + &h->interrupt_callback, NULL)) < 0) break; /* creating size */ diff --git a/libavformat/crypto.c b/libavformat/crypto.c index ea417470b6..7095360c85 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -82,7 +82,8 @@ static int crypto_open(URLContext *h, const char *uri, int flags) ret = AVERROR(ENOSYS); goto err; } - if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ)) < 0) { + if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ, + &h->interrupt_callback, NULL)) < 0) { av_log(h, AV_LOG_ERROR, "Unable to open input\n"); goto err; } diff --git a/libavformat/gopher.c b/libavformat/gopher.c index 9eeffaca28..6a829c8ce5 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -100,7 +100,8 @@ static int gopher_open(URLContext *h, const char *uri, int flags) ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); s->hd = NULL; - err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&s->hd, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); if (err < 0) goto fail; diff --git a/libavformat/http.c b/libavformat/http.c index 2e6eb1627d..ad4018085c 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -133,7 +133,8 @@ static int http_open_cnx(URLContext *h) port = 80; ff_url_join(buf, sizeof(buf), lower_proto, NULL, hostname, port, NULL); - err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); if (err < 0) goto fail; diff --git a/libavformat/img2.c b/libavformat/img2.c index 444a6dfd7a..ff159ebf91 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -310,7 +310,8 @@ static int read_packet(AVFormatContext *s1, AVPacket *pkt) s->path, s->img_number)<0 && s->img_number > 1) return AVERROR(EIO); for(i=0; i<3; i++){ - if (avio_open(&f[i], filename, AVIO_FLAG_READ) < 0) { + if (avio_open2(&f[i], filename, AVIO_FLAG_READ, + &s1->interrupt_callback, NULL) < 0) { if(i==1) break; av_log(s1, AV_LOG_ERROR, "Could not open file : %s\n",filename); @@ -397,7 +398,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EINVAL); } for(i=0; i<3; i++){ - if (avio_open(&pb[i], filename, AVIO_FLAG_WRITE) < 0) { + if (avio_open2(&pb[i], filename, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL) < 0) { av_log(s, AV_LOG_ERROR, "Could not open file : %s\n",filename); return AVERROR(EIO); } diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 3f099da440..4e041b020f 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -65,7 +65,8 @@ static int md5_close(URLContext *h) av_strstart(filename, "md5:", &filename); if (*filename) { - err = ffurl_open(&out, filename, AVIO_FLAG_WRITE); + err = ffurl_open(&out, filename, AVIO_FLAG_WRITE, + &h->interrupt_callback, NULL); if (err) return err; err = ffurl_write(out, buf, i*2+1); diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index c710ad9ccc..47cfea020b 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -234,7 +234,8 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim port = 80; // default mmsh protocol port ff_url_join(httpname, sizeof(httpname), "http", NULL, host, port, "%s", path); - if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, + &h->interrupt_callback) < 0) { return AVERROR(EIO); } @@ -249,7 +250,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim host, port, mmsh->request_seq++); av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); - err = ffurl_connect(mms->mms_hd); + err = ffurl_connect(mms->mms_hd, NULL); if (err) { goto fail; } @@ -262,7 +263,8 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim // close the socket and then reopen it for sending the second play request. ffurl_close(mms->mms_hd); memset(headers, 0, sizeof(headers)); - if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&mms->mms_hd, httpname, AVIO_FLAG_READ, + &h->interrupt_callback) < 0) { return AVERROR(EIO); } stream_selection = av_mallocz(mms->stream_num * 19 + 1); @@ -296,7 +298,7 @@ static int mmsh_open_internal(URLContext *h, const char *uri, int flags, int tim av_dlog(NULL, "out_buffer is %s", headers); av_opt_set(mms->mms_hd->priv_data, "headers", headers, 0); - err = ffurl_connect(mms->mms_hd); + err = ffurl_connect(mms->mms_hd, NULL); if (err) { goto fail; } diff --git a/libavformat/mmst.c b/libavformat/mmst.c index a3db288b35..0a728eb35f 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -523,7 +523,8 @@ static int mms_open(URLContext *h, const char *uri, int flags) // establish tcp connection. ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, mmst->host, port, NULL); - err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE); + err = ffurl_open(&mms->mms_hd, tcpname, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); if (err) goto fail; diff --git a/libavformat/mov.c b/libavformat/mov.c index c107f11f51..51dd3eb498 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1837,7 +1837,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } } -static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref) +static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref, + AVIOInterruptCB *int_cb) { /* try relative path, we do not try the absolute because it can leak information about our system to an attacker */ @@ -1872,7 +1873,7 @@ static int mov_open_dref(AVIOContext **pb, const char *src, MOVDref *ref) av_strlcat(filename, ref->path + l + 1, 1024); - if (!avio_open(pb, filename, AVIO_FLAG_READ)) + if (!avio_open2(pb, filename, AVIO_FLAG_READ, int_cb, NULL)) return 0; } } @@ -1927,7 +1928,7 @@ static int mov_read_trak(MOVContext *c, AVIOContext *pb, MOVAtom atom) if (sc->dref_id-1 < sc->drefs_count && sc->drefs[sc->dref_id-1].path) { MOVDref *dref = &sc->drefs[sc->dref_id - 1]; - if (mov_open_dref(&sc->pb, c->fc->filename, dref) < 0) + if (mov_open_dref(&sc->pb, c->fc->filename, dref, &c->fc->interrupt_callback) < 0) av_log(c->fc, AV_LOG_ERROR, "stream %d, error opening alias: path='%s', dir='%s', " "filename='%s', volume='%s', nlvl_from=%d, nlvl_to=%d\n", diff --git a/libavformat/options.c b/libavformat/options.c index 64bc7a8996..4afb8b52bc 100644 --- a/libavformat/options.c +++ b/libavformat/options.c @@ -18,6 +18,7 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include "avformat.h" +#include "avio_internal.h" #include "libavutil/opt.h" /** @@ -40,6 +41,10 @@ static void *format_child_next(void *obj, void *prev) ((s->iformat && s->iformat->priv_class) || s->oformat && s->oformat->priv_class)) return s->priv_data; +#if !FF_API_OLD_AVIO + if (s->pb && s->pb->av_class && prev != s->pb) + return s->pb; +#endif return NULL; } @@ -49,19 +54,29 @@ static const AVClass *format_child_class_next(const AVClass *prev) AVOutputFormat *ofmt = NULL; while (prev && (ifmt = av_iformat_next(ifmt))) - if (ifmt->priv_class == prev) + if (ifmt->priv_class == prev){ + prev = NULL; break; - if ((prev && ifmt) || (!prev)) + } + if (!prev) while (ifmt = av_iformat_next(ifmt)) if (ifmt->priv_class) return ifmt->priv_class; while (prev && (ofmt = av_oformat_next(ofmt))) - if (ofmt->priv_class == prev) + if (ofmt->priv_class == prev){ + prev = NULL; break; - while (ofmt = av_oformat_next(ofmt)) - if (ofmt->priv_class) - return ofmt->priv_class; + } + if (!prev) + while (ofmt = av_oformat_next(ofmt)) + if (ofmt->priv_class) + return ofmt->priv_class; + +#if !FF_API_OLD_AVIO + if (prev != &ffio_url_class) + return &ffio_url_class; +#endif return NULL; } diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index ed483cf37f..e73158f12c 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -817,7 +817,8 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) port = RTMP_DEFAULT_PORT; ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); - if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index f4590faa08..8a5adf54ed 100644 --- a/libavformat/rtpenc_chain.c +++ b/libavformat/rtpenc_chain.c @@ -47,6 +47,8 @@ AVFormatContext *ff_rtp_chain_mux_open(AVFormatContext *s, AVStream *st, av_free(rtpctx); return NULL; } + /* Pass the interrupt callback on */ + rtpctx->interrupt_callback = s->interrupt_callback; /* Copy the max delay setting; the rtp muxer reads this. */ rtpctx->max_delay = s->max_delay; /* Copy other stream parameters. */ diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 4f4cde621c..41fb7317bb 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -189,7 +189,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) build_udp_url(buf, sizeof(buf), hostname, rtp_port, local_rtp_port, ttl, max_packet_size, connect); - if (ffurl_open(&s->rtp_hd, buf, flags) < 0) + if (ffurl_open(&s->rtp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) goto fail; if (local_rtp_port>=0 && local_rtcp_port<0) local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1; @@ -197,7 +197,7 @@ static int rtp_open(URLContext *h, const char *uri, int flags) build_udp_url(buf, sizeof(buf), hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size, connect); - if (ffurl_open(&s->rtcp_hd, buf, flags) < 0) + if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0) goto fail; /* just to ease handle access. XXX: need to suppress direct handle @@ -227,7 +227,7 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size) struct pollfd p[2] = {{s->rtp_fd, POLLIN, 0}, {s->rtcp_fd, POLLIN, 0}}; for(;;) { - if (url_interrupt_cb()) + if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; /* build fdset to listen to RTP and RTCP packets */ n = poll(p, 2, 100); diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 68083ae2ac..18ec8a5edc 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1159,7 +1159,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, "?localport=%d", j); /* we will use two ports per rtp stream (rtp and rtcp) */ j += 2; - if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE) == 0) + if (ffurl_open(&rtsp_st->rtp_handle, buf, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL) == 0) goto rtp_opened; } } @@ -1306,7 +1307,8 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, namebuf, sizeof(namebuf), NULL, 0, NI_NUMERICHOST); ff_url_join(url, sizeof(url), "rtp", NULL, namebuf, port, "?ttl=%d", ttl); - if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1450,7 +1452,8 @@ redirect: av_get_random_seed(), av_get_random_seed()); /* GET requests */ - if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ) < 0) { + if (ffurl_alloc(&rt->rtsp_hd, httpname, AVIO_FLAG_READ, + &s->interrupt_callback) < 0) { err = AVERROR(EIO); goto fail; } @@ -1465,13 +1468,14 @@ redirect: av_opt_set(rt->rtsp_hd->priv_data, "headers", headers, 0); /* complete the connection */ - if (ffurl_connect(rt->rtsp_hd)) { + if (ffurl_connect(rt->rtsp_hd, NULL)) { err = AVERROR(EIO); goto fail; } /* POST requests */ - if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE) < 0 ) { + if (ffurl_alloc(&rt->rtsp_hd_out, httpname, AVIO_FLAG_WRITE, + &s->interrupt_callback) < 0 ) { err = AVERROR(EIO); goto fail; } @@ -1507,14 +1511,15 @@ redirect: ff_http_init_auth_state(rt->rtsp_hd_out, rt->rtsp_hd); /* complete the connection */ - if (ffurl_connect(rt->rtsp_hd_out)) { + if (ffurl_connect(rt->rtsp_hd_out, NULL)) { err = AVERROR(EIO); goto fail; } } else { /* open the tcp connection */ ff_url_join(tcpname, sizeof(tcpname), "tcp", NULL, host, port, NULL); - if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rt->rtsp_hd, tcpname, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL) < 0) { err = AVERROR(EIO); goto fail; } @@ -1619,7 +1624,7 @@ static int udp_read_packet(AVFormatContext *s, RTSPStream **prtsp_st, struct pollfd *p = rt->p; for (;;) { - if (url_interrupt_cb()) + if (ff_check_interrupt(&s->interrupt_callback)) return AVERROR_EXIT; if (wait_end && wait_end - av_gettime() < 0) return AVERROR(EAGAIN); @@ -1862,7 +1867,8 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) "?localport=%d&ttl=%d&connect=%d", rtsp_st->sdp_port, rtsp_st->sdp_ttl, rt->rtsp_flags & RTSP_FLAG_FILTER_SRC ? 1 : 0); - if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE) < 0) { + if (ffurl_open(&rtsp_st->rtp_handle, url, AVIO_FLAG_READ_WRITE, + &s->interrupt_callback, NULL) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1926,7 +1932,8 @@ static int rtp_read_header(AVFormatContext *s, if (!ff_network_init()) return AVERROR(EIO); - ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ); + ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ, + &s->interrupt_callback, NULL); if (ret) goto fail; diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 68e3c5c095..00e34b7387 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -85,7 +85,8 @@ static int sap_read_header(AVFormatContext *s, ff_url_join(url, sizeof(url), "udp", NULL, host, port, "?localport=%d", port); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ); + ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ, + &s->interrupt_callback, NULL); if (ret) goto fail; @@ -157,6 +158,7 @@ static int sap_read_header(AVFormatContext *s, } sap->sdp_ctx->max_delay = s->max_delay; sap->sdp_ctx->pb = &sap->sdp_pb; + sap->sdp_ctx->interrupt_callback = s->interrupt_callback; ret = avformat_open_input(&sap->sdp_ctx, "temp.sdp", infmt, NULL); if (ret < 0) goto fail; diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index b84cce50a4..0f2b4b51f0 100644 --- a/libavformat/sapenc.c +++ b/libavformat/sapenc.c @@ -146,7 +146,7 @@ static int sap_write_header(AVFormatContext *s) "?ttl=%d", ttl); if (!same_port) base_port += 2; - ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE); + ret = ffurl_open(&fd, url, AVIO_FLAG_WRITE, &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; @@ -158,7 +158,8 @@ static int sap_write_header(AVFormatContext *s) ff_url_join(url, sizeof(url), "udp", NULL, announce_addr, port, "?ttl=%d&connect=1", ttl); - ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE); + ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_WRITE, + &s->interrupt_callback, NULL); if (ret) { ret = AVERROR(EIO); goto fail; diff --git a/libavformat/tcp.c b/libavformat/tcp.c index eb982d5675..f882fc0dee 100644 --- a/libavformat/tcp.c +++ b/libavformat/tcp.c @@ -100,7 +100,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) struct pollfd p = {fd, POLLOUT, 0}; ret = ff_neterrno(); if (ret == AVERROR(EINTR)) { - if (url_interrupt_cb()) { + if (ff_check_interrupt(&h->interrupt_callback)) { ret = AVERROR_EXIT; goto fail1; } @@ -112,7 +112,7 @@ static int tcp_open(URLContext *h, const char *uri, int flags) /* wait until we are connected or until abort */ while(timeout--) { - if (url_interrupt_cb()) { + if (ff_check_interrupt(&h->interrupt_callback)) { ret = AVERROR_EXIT; goto fail1; } diff --git a/libavformat/tls.c b/libavformat/tls.c index 8211e88846..33ee782fa8 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -97,7 +97,7 @@ static int do_tls_poll(URLContext *h, int ret) int n = poll(&p, 1, 100); if (n > 0) break; - if (url_interrupt_cb()) + if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR(EINTR); } return 0; @@ -123,7 +123,8 @@ static int tls_open(URLContext *h, const char *uri, int flags) freeaddrinfo(ai); } - ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE); + ret = ffurl_open(&c->tcp, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); if (ret) goto fail; c->fd = ffurl_get_file_handle(c->tcp); diff --git a/libavformat/url.h b/libavformat/url.h index 103f7b6c00..dbcf470d69 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -28,11 +28,16 @@ #include "avio.h" #include "libavformat/version.h" +#include "libavutil/dict.h" +#include "libavutil/log.h" + #if !FF_API_OLD_AVIO #define URL_PROTOCOL_FLAG_NESTED_SCHEME 1 /*< The protocol name can be the first part of a nested protocol scheme */ extern int (*url_interrupt_cb)(void); +extern const AVClass ffurl_context_class; + typedef struct URLContext { const AVClass *av_class; /**< information for av_log(). Set by url_open(). */ struct URLProtocol *prot; @@ -42,11 +47,18 @@ typedef struct URLContext { int max_packet_size; /**< if non zero, the stream is packetized with this max packet size */ int is_streamed; /**< true if streamed (no seek possible), default = false */ int is_connected; + AVIOInterruptCB interrupt_callback; } URLContext; typedef struct URLProtocol { const char *name; int (*url_open)( URLContext *h, const char *url, int flags); + /** + * This callback is to be used by protocols which open further nested + * protocols. options are then to be passed to ffurl_open()/ffurl_connect() + * for those nested protocols. + */ + int (*url_open2)(URLContext *h, const char *url, int flags, AVDictionary **options); int (*url_read)( URLContext *h, unsigned char *buf, int size); int (*url_write)(URLContext *h, const unsigned char *buf, int size); int64_t (*url_seek)( URLContext *h, int64_t pos, int whence); @@ -71,15 +83,23 @@ typedef struct URLProtocol { * function puts the pointer to the created URLContext * @param flags flags which control how the resource indicated by url * is to be opened + * @param int_cb interrupt callback to use for the URLContext, may be + * NULL * @return 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ -int ffurl_alloc(URLContext **puc, const char *filename, int flags); +int ffurl_alloc(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb); /** * Connect an URLContext that has been allocated by ffurl_alloc + * + * @param options A dictionary filled with options for nested protocols, + * i.e. it will be passed to url_open2() for protocols implementing it. + * This parameter will be destroyed and replaced with a dict containing options + * that were not found. May be NULL. */ -int ffurl_connect(URLContext *uc); +int ffurl_connect(URLContext *uc, AVDictionary **options); /** * Create an URLContext for accessing to the resource indicated by @@ -89,10 +109,16 @@ int ffurl_connect(URLContext *uc); * function puts the pointer to the created URLContext * @param flags flags which control how the resource indicated by url * is to be opened + * @param int_cb interrupt callback to use for the URLContext, may be + * NULL + * @param options A dictionary filled with protocol-private options. On return + * this parameter will be destroyed and replaced with a dict containing options + * that were not found. May be NULL. * @return 0 in case of success, a negative value corresponding to an * AVERROR code in case of failure */ -int ffurl_open(URLContext **puc, const char *filename, int flags); +int ffurl_open(URLContext **puc, const char *filename, int flags, + const AVIOInterruptCB *int_cb, AVDictionary **options); /** * Read up to size bytes from the resource accessed by h, and store @@ -169,6 +195,19 @@ int ffurl_get_file_handle(URLContext *h); */ int ffurl_register_protocol(URLProtocol *protocol, int size); +/** + * Check if the user has requested to interrup a blocking function + * associated with cb. + */ +int ff_check_interrupt(AVIOInterruptCB *cb); + +/** + * Iterate over all available protocols. + * + * @param prev result of the previous call to this functions or NULL. + */ +URLProtocol *ffurl_protocol_next(URLProtocol *prev); + /* udp.c */ int ff_udp_set_remote_url(URLContext *h, const char *uri); int ff_udp_get_local_port(URLContext *h); diff --git a/libavformat/utils.c b/libavformat/utils.c index c7916dc407..93a48418bc 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -602,7 +602,7 @@ int av_open_input_file(AVFormatContext **ic_ptr, const char *filename, #endif /* open input file and probe the format if necessary */ -static int init_input(AVFormatContext *s, const char *filename) +static int init_input(AVFormatContext *s, const char *filename, AVDictionary **options) { int ret; AVProbeData pd = {filename, NULL, 0}; @@ -624,7 +624,8 @@ static int init_input(AVFormatContext *s, const char *filename) (!s->iformat && (s->iformat = av_probe_input_format(&pd, 0)))) return 0; - if ((ret = avio_open(&s->pb, filename, AVIO_FLAG_READ)) < 0) + if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ, + &s->interrupt_callback, options)) < 0) return ret; if (s->iformat) return 0; @@ -649,7 +650,7 @@ int avformat_open_input(AVFormatContext **ps, const char *filename, AVInputForma if ((ret = av_opt_set_dict(s, &tmp)) < 0) goto fail; - if ((ret = init_input(s, filename)) < 0) + if ((ret = init_input(s, filename, &tmp)) < 0) goto fail; /* check filename in case an image number is expected */ @@ -2396,7 +2397,7 @@ int avformat_find_stream_info(AVFormatContext *ic, AVDictionary **options) count = 0; read_size = 0; for(;;) { - if(url_interrupt_cb()){ + if (ff_check_interrupt(&ic->interrupt_callback)){ ret= AVERROR_EXIT; av_log(ic, AV_LOG_DEBUG, "interrupted\n"); break; |