From 8283f90a52ee5feb5292df3707d4846c3c5d8049 Mon Sep 17 00:00:00 2001 From: "Ronald S. Bultje" Date: Sun, 13 Nov 2011 05:40:41 +0100 Subject: [PATCH 01/13] swscale: handle unaligned buffers in yuv2plane1 The issue had been introduced in c435653627529e22d74214c2266f571255e404d6 Signed-off-by: Luca Barbato --- libswscale/x86/scale.asm | 2 ++ 1 file changed, 2 insertions(+) diff --git a/libswscale/x86/scale.asm b/libswscale/x86/scale.asm index 64699ea175..3bdf71b542 100644 --- a/libswscale/x86/scale.asm +++ b/libswscale/x86/scale.asm @@ -718,6 +718,8 @@ yuv2planeX_fn avx, 10, 7, 5 %macro yuv2plane1_fn 3 cglobal yuv2plane1_%1, %3, %3, %2 + add r2, mmsize - 1 + and r2, ~(mmsize - 1) %if %1 == 8 add r1, r2 %else ; %1 != 8 From 84fb63ed23855f3c86b846c0d3f8b017ae76aae1 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 13 Nov 2011 04:05:13 +0100 Subject: [PATCH 02/13] doc: prettyfy the texi2html documentation make it use the website css and start structuring it so it is consistent --- doc/t2h.init | 64 ++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/doc/t2h.init b/doc/t2h.init index cd38a3ec9e..d464aa1c00 100644 --- a/doc/t2h.init +++ b/doc/t2h.init @@ -1,15 +1,69 @@ # no horiz rules between sections -$end_section = \&FFMPEG_end_section; -sub FFMPEG_end_section($$) +$end_section = \&Libav_end_section; +sub Libav_end_section($$) { } -$print_page_foot = \&FFMPEG_print_page_foot; -sub FFMPEG_print_page_foot($$) +$EXTRA_HEAD = + '\n' . + '\n'; + +$AFTER_BODY_OPEN = '
'. + '
'; + +$PRE_BODY_CLOSE = '
'; + +$SMALL_RULE = ''; +$BODYTEXT = ''; + +$print_page_foot = \&Libav_print_page_foot; +sub Libav_print_page_foot($$) { my $fh = shift; - print $fh "$SMALL_RULE\n"; + print $fh '\n'; +} + +$print_page_head = \&Libav_print_page_head; +sub Libav_print_page_head($$) +{ + my $fh = shift; + my $longtitle = "$Texi2HTML::THISDOC{'title_no_texi'}"; + $longtitle .= ": $Texi2HTML::NO_TEXI{'This'}" if exists $Texi2HTML::NO_TEXI{'This'}; + my $description = $DOCUMENT_DESCRIPTION; + $description = $longtitle if (!defined($description)); + $description = "" if + ($description ne ''); + $description = $Texi2HTML::THISDOC{'documentdescription'} if (defined($Texi2HTML::THISDOC{'documentdescription'})); + my $encoding = ''; + $encoding = "" if (defined($ENCODING) and ($ENCODING ne '')); + $longtitle =~ s/Documentation.*//g; + $longtitle = "Libav documentation : " . $longtitle; + + print $fh < +$Texi2HTML::THISDOC{'copying'} + + +$longtitle + +$description + + + + +$encoding +$CSS_LINES +$EXTRA_HEAD + + + +$AFTER_BODY_OPEN +EOT } # no navigation elements From 58b68d6b36d4c88f9250fd4f57f87fea41cc5e10 Mon Sep 17 00:00:00 2001 From: Luca Barbato Date: Sun, 13 Nov 2011 12:25:29 +0100 Subject: [PATCH 03/13] texi2html: remove stray \n Single-quoted strings are printed verbatim in perl. --- doc/t2h.init | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/doc/t2h.init b/doc/t2h.init index d464aa1c00..59a5ed8d5e 100644 --- a/doc/t2h.init +++ b/doc/t2h.init @@ -5,11 +5,13 @@ sub Libav_end_section($$) } $EXTRA_HEAD = - '\n' . - '\n'; +' + +'; -$AFTER_BODY_OPEN = '
'. - '
'; +$AFTER_BODY_OPEN = +'
+
'; $PRE_BODY_CLOSE = '
'; @@ -20,9 +22,9 @@ $print_page_foot = \&Libav_print_page_foot; sub Libav_print_page_foot($$) { my $fh = shift; - print $fh '\n"; } $print_page_head = \&Libav_print_page_head; From 6aa0b98fb27ab22bd62a365de44d9f16cc07d03e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 14:10:16 +0200 Subject: [PATCH 04/13] avio: Add AVIOInterruptCB This is a better io interrupt callback function, which has an opaque parameter, which is given to the interrupt callback. This allows callers to precisely cancel IO for one single AVFormatContext, without interrupt other ones in the same process. Note, it's not needed in AVIOContext, at the moment. Signed-off-by: Anton Khirnov --- libavformat/avformat.h | 11 +++++++++++ libavformat/avio.h | 17 +++++++++++++++++ libavformat/url.h | 1 + 3 files changed, 29 insertions(+) diff --git a/libavformat/avformat.h b/libavformat/avformat.h index 82d245e688..33e820e4e1 100644 --- a/libavformat/avformat.h +++ b/libavformat/avformat.h @@ -994,6 +994,17 @@ 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; + /***************************************************************** * 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.h b/libavformat/avio.h index be14e3c89d..a4041cb770 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -35,6 +35,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. @@ -109,6 +125,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 */ diff --git a/libavformat/url.h b/libavformat/url.h index d69d0bc5c5..c0f532278f 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -42,6 +42,7 @@ 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 { From c4a090ddb564b87fd9d6d4f83e0f134a77c96007 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 22:10:21 +0200 Subject: [PATCH 05/13] avio: Add an internal utility function for checking the new interrupt callback Signed-off-by: Anton Khirnov --- libavformat/avio.c | 8 ++++++++ libavformat/url.h | 6 ++++++ 2 files changed, 14 insertions(+) diff --git a/libavformat/avio.c b/libavformat/avio.c index 8e1854976e..1964012b1d 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -408,6 +408,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/url.h b/libavformat/url.h index c0f532278f..de10033710 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -170,6 +170,12 @@ 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); + /* udp.c */ int ff_udp_set_remote_url(URLContext *h, const char *uri); int ff_udp_get_local_port(URLContext *h); From 9957cdbfd5ced5baae6ec97b97b08f1ad42aa4e4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 22:34:24 +0200 Subject: [PATCH 06/13] avformat: Use ff_check_interrupt --- libavformat/applehttp.c | 5 ++++- libavformat/applehttpproto.c | 4 ++-- libavformat/avio.c | 2 +- libavformat/rtpproto.c | 2 +- libavformat/rtsp.c | 2 +- libavformat/tcp.c | 4 ++-- libavformat/tls.c | 2 +- libavformat/utils.c | 2 +- 8 files changed, 13 insertions(+), 10 deletions(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index eadb230045..06884a07c6 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) @@ -388,7 +389,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 +434,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 85f3cfcef4..1476ea28f2 100644 --- a/libavformat/applehttpproto.c +++ b/libavformat/applehttpproto.c @@ -266,7 +266,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); } @@ -276,7 +276,7 @@ retry: av_log(h, AV_LOG_DEBUG, "opening %s\n", url); ret = ffurl_open(&s->seg_hd, url, AVIO_FLAG_READ); 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/avio.c b/libavformat/avio.c index 1964012b1d..c66e2caac3 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -284,7 +284,7 @@ static inline int retry_transfer_wrapper(URLContext *h, unsigned char *buf, int 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; diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 9a18157df5..1bb0a4b8a6 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -226,7 +226,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 8f7bd3718f..5bdb7fa6a4 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1619,7 +1619,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); diff --git a/libavformat/tcp.c b/libavformat/tcp.c index e602a556d2..fda34a368d 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..15d51f3784 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; diff --git a/libavformat/utils.c b/libavformat/utils.c index c2beeaee7a..91760c89ab 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -2310,7 +2310,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; From 6f1b7b39449c4cd58e37d831d5d97bfd25eb26f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 22:50:44 +0200 Subject: [PATCH 07/13] avio: Add an AVIOInterruptCB parameter to ffurl_open/ffurl_alloc Change all uses of these function to pass the relevant callback on. --- libavformat/applehttp.c | 9 ++++++--- libavformat/applehttpproto.c | 3 ++- libavformat/avio.c | 27 ++++++++++++++++----------- libavformat/aviobuf.c | 2 +- libavformat/concat.c | 2 +- libavformat/crypto.c | 3 ++- libavformat/gopher.c | 2 +- libavformat/http.c | 2 +- libavformat/md5proto.c | 2 +- libavformat/mmsh.c | 6 ++++-- libavformat/mmst.c | 3 ++- libavformat/rtmpproto.c | 3 ++- libavformat/rtpproto.c | 4 ++-- libavformat/rtsp.c | 21 ++++++++++++++------- libavformat/sapdec.c | 2 +- libavformat/sapenc.c | 4 ++-- libavformat/tls.c | 2 +- libavformat/url.h | 10 ++++++++-- 18 files changed, 67 insertions(+), 40 deletions(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index 06884a07c6..ae251531e8 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -323,13 +323,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); } 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) == 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", @@ -349,7 +351,8 @@ 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); diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c index 1476ea28f2..e8d1b495ed 100644 --- a/libavformat/applehttpproto.c +++ b/libavformat/applehttpproto.c @@ -274,7 +274,8 @@ 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); if (ret < 0) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; diff --git a/libavformat/avio.c b/libavformat/avio.c index c66e2caac3..c17c1c4438 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -86,7 +86,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; @@ -114,6 +115,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; @@ -145,7 +148,7 @@ 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); @@ -158,7 +161,7 @@ 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) { @@ -166,7 +169,7 @@ 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) { @@ -219,7 +222,8 @@ 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; char proto_str[128], proto_nested[128], *ptr; @@ -237,19 +241,20 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags) 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); @@ -348,7 +353,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) < 0) return 0; ffurl_close(h); return 1; @@ -358,7 +363,7 @@ 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; diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index 8bd3e78446..b2bd6f8dc8 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -932,7 +932,7 @@ int avio_open(AVIOContext **s, const char *filename, int flags) URLContext *h; int err; - err = ffurl_open(&h, filename, flags); + err = ffurl_open(&h, filename, flags, NULL); if (err < 0) return err; err = ffio_fdopen(s, h); diff --git a/libavformat/concat.c b/libavformat/concat.c index da9bee2cc4..47f97ef1e7 100644 --- a/libavformat/concat.c +++ b/libavformat/concat.c @@ -101,7 +101,7 @@ 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)) < 0) break; /* creating size */ diff --git a/libavformat/crypto.c b/libavformat/crypto.c index ea417470b6..5171b1256b 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)) < 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 79d1feba6b..afb0aff98d 100644 --- a/libavformat/gopher.c +++ b/libavformat/gopher.c @@ -100,7 +100,7 @@ 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); if (err < 0) goto fail; diff --git a/libavformat/http.c b/libavformat/http.c index a8a76882dd..dbf384efff 100644 --- a/libavformat/http.c +++ b/libavformat/http.c @@ -133,7 +133,7 @@ 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); if (err < 0) goto fail; diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index 4630c49f5c..f136e805f9 100644 --- a/libavformat/md5proto.c +++ b/libavformat/md5proto.c @@ -65,7 +65,7 @@ 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); if (err) return err; err = ffurl_write(out, buf, i*2+1); diff --git a/libavformat/mmsh.c b/libavformat/mmsh.c index cbce2f5284..6ea1592d42 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -233,7 +233,8 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) 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); } @@ -261,7 +262,8 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) // 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); diff --git a/libavformat/mmst.c b/libavformat/mmst.c index e1904de1e2..e69d330e1b 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); if (err) goto fail; diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 093d21a585..98e6180c92 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) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index 1bb0a4b8a6..ca5007667a 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -188,7 +188,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) < 0) goto fail; if (local_rtp_port>=0 && local_rtcp_port<0) local_rtcp_port = ff_udp_get_local_port(s->rtp_hd) + 1; @@ -196,7 +196,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) < 0) goto fail; /* just to ease handle access. XXX: need to suppress direct handle diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index 5bdb7fa6a4..d07cd406ed 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) == 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) < 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; } @@ -1471,7 +1474,8 @@ redirect: } /* 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; } @@ -1514,7 +1518,8 @@ redirect: } 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) < 0) { err = AVERROR(EIO); goto fail; } @@ -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) < 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); if (ret) goto fail; diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 84a9eb17b3..21f893554f 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -85,7 +85,7 @@ 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); if (ret) goto fail; diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index 06cac938f3..ec017909eb 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); if (ret) { ret = AVERROR(EIO); goto fail; @@ -158,7 +158,7 @@ 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); if (ret) { ret = AVERROR(EIO); goto fail; diff --git a/libavformat/tls.c b/libavformat/tls.c index 15d51f3784..b2ec147adb 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -123,7 +123,7 @@ 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); if (ret) goto fail; c->fd = ffurl_get_file_handle(c->tcp); diff --git a/libavformat/url.h b/libavformat/url.h index de10033710..03ba15fdda 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -72,10 +72,13 @@ 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 @@ -90,10 +93,13 @@ 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 * @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); /** * Read up to size bytes from the resource accessed by h, and store From 6ef350c16bf9a375a1ea3e531019ea922ae5a1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 22:55:40 +0200 Subject: [PATCH 08/13] avformat: Pass the interrupt callback on to chained muxers/demuxers There are a few more cases of chained demuxers, but they only use custom IO which don't do any blocking IO and thus don't need the callback. --- libavformat/rtpenc_chain.c | 2 ++ libavformat/sapdec.c | 1 + 2 files changed, 3 insertions(+) diff --git a/libavformat/rtpenc_chain.c b/libavformat/rtpenc_chain.c index f0e4dae8eb..b9d1690008 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/sapdec.c b/libavformat/sapdec.c index 21f893554f..7b950cd617 100644 --- a/libavformat/sapdec.c +++ b/libavformat/sapdec.c @@ -157,6 +157,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; From 163a31136dcb0b5966fc779917e0408cb52d7295 Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 5 Nov 2011 11:42:13 +0100 Subject: [PATCH 09/13] avio: add and use ffurl_protocol_next(). --- libavformat/avio.c | 19 +++++++++++-------- libavformat/url.h | 7 +++++++ 2 files changed, 18 insertions(+), 8 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index c17c1c4438..06972cdbdd 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -30,6 +30,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) @@ -49,21 +56,19 @@ static const AVClass urlcontext_class = { static int default_interrupt_cb(void); -URLProtocol *first_protocol = NULL; 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; + return ffurl_protocol_next(p); } #endif const char *avio_enum_protocols(void **opaque, int output) { URLProtocol **p = opaque; - *p = *p ? (*p)->next : first_protocol; + *p = ffurl_protocol_next(*p); if (!*p) return NULL; if ((output && (*p)->url_write) || (!output && (*p)->url_read)) return (*p)->name; @@ -225,7 +230,7 @@ int av_register_protocol2(URLProtocol *protocol, int size) 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); @@ -238,14 +243,12 @@ 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, int_cb); if (up->flags & URL_PROTOCOL_FLAG_NESTED_SCHEME && !strcmp(proto_nested, up->name)) return url_alloc_for_protocol (puc, up, filename, flags, int_cb); - up = up->next; } *puc = NULL; return AVERROR(ENOENT); diff --git a/libavformat/url.h b/libavformat/url.h index 03ba15fdda..902539aa64 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -182,6 +182,13 @@ int ffurl_register_protocol(URLProtocol *protocol, int size); */ 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); From ddffc2fdc351d60ca190b016cccff4acff27823f Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 5 Nov 2011 10:04:04 +0100 Subject: [PATCH 10/13] avio: add support for passing options to protocols. Not used anywhere yet, support for passing options from avio_open() will follow. --- libavformat/applehttp.c | 6 ++-- libavformat/applehttpproto.c | 2 +- libavformat/avio.c | 55 ++++++++++++++++++++++++++++++------ libavformat/aviobuf.c | 2 +- libavformat/concat.c | 3 +- libavformat/crypto.c | 2 +- libavformat/gopher.c | 3 +- libavformat/http.c | 3 +- libavformat/md5proto.c | 3 +- libavformat/mmsh.c | 4 +-- libavformat/mmst.c | 2 +- libavformat/rtmpproto.c | 2 +- libavformat/rtpproto.c | 4 +-- libavformat/rtsp.c | 14 ++++----- libavformat/sapdec.c | 3 +- libavformat/sapenc.c | 5 ++-- libavformat/tls.c | 3 +- libavformat/url.h | 20 +++++++++++-- 18 files changed, 98 insertions(+), 38 deletions(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index ae251531e8..74d9f781e3 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -324,14 +324,14 @@ 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, - &var->parent->interrupt_callback); + &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, - &var->parent->interrupt_callback) == 0) { + &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", @@ -356,7 +356,7 @@ static int open_input(struct variant *var) 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; diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c index e8d1b495ed..2123423452 100644 --- a/libavformat/applehttpproto.c +++ b/libavformat/applehttpproto.c @@ -275,7 +275,7 @@ 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, - &h->interrupt_callback); + &h->interrupt_callback, NULL); if (ret < 0) { if (ff_check_interrupt(&h->interrupt_callback)) return AVERROR_EXIT; diff --git a/libavformat/avio.c b/libavformat/avio.c index 06972cdbdd..330d52cfec 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -22,6 +22,7 @@ #include #include "libavutil/avstring.h" +#include "libavutil/dict.h" #include "libavutil/opt.h" #include "os_support.h" #include "avformat.h" @@ -45,12 +46,40 @@ 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 = { .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, }; /*@}*/ @@ -133,9 +162,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; @@ -156,7 +189,7 @@ int url_open_protocol (URLContext **puc, struct URLProtocol *up, 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: @@ -170,11 +203,11 @@ int url_alloc(URLContext **puc, const char *filename, int flags) } 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, NULL); + return ffurl_open(puc, filename, flags, NULL, NULL); } int url_read(URLContext *h, unsigned char *buf, int size) { @@ -255,14 +288,18 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, } int ffurl_open(URLContext **puc, const char *filename, int flags, - const AVIOInterruptCB *int_cb) + const AVIOInterruptCB *int_cb, AVDictionary **options) { 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; @@ -356,7 +393,7 @@ int ffurl_close(URLContext *h) int url_exist(const char *filename) { URLContext *h; - if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL) < 0) + if (ffurl_open(&h, filename, AVIO_FLAG_READ, NULL, NULL) < 0) return 0; ffurl_close(h); return 1; @@ -373,7 +410,7 @@ int avio_check(const char *url, int flags) 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; } diff --git a/libavformat/aviobuf.c b/libavformat/aviobuf.c index b2bd6f8dc8..246903baac 100644 --- a/libavformat/aviobuf.c +++ b/libavformat/aviobuf.c @@ -932,7 +932,7 @@ int avio_open(AVIOContext **s, const char *filename, int flags) URLContext *h; int err; - err = ffurl_open(&h, filename, flags, NULL); + err = ffurl_open(&h, filename, flags, NULL, NULL); if (err < 0) return err; err = ffio_fdopen(s, h); diff --git a/libavformat/concat.c b/libavformat/concat.c index 47f97ef1e7..1501cbcba4 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, &h->interrupt_callback)) < 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 5171b1256b..7095360c85 100644 --- a/libavformat/crypto.c +++ b/libavformat/crypto.c @@ -83,7 +83,7 @@ static int crypto_open(URLContext *h, const char *uri, int flags) goto err; } if ((ret = ffurl_open(&c->hd, nested_url, AVIO_FLAG_READ, - &h->interrupt_callback)) < 0) { + &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 afb0aff98d..5f8c320f10 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, &h->interrupt_callback); + 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 dbf384efff..9cc55bd3fc 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, &h->interrupt_callback); + err = ffurl_open(&hd, buf, AVIO_FLAG_READ_WRITE, + &h->interrupt_callback, NULL); if (err < 0) goto fail; diff --git a/libavformat/md5proto.c b/libavformat/md5proto.c index f136e805f9..8e61e5be4c 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, &h->interrupt_callback); + 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 6ea1592d42..50e160f7ba 100644 --- a/libavformat/mmsh.c +++ b/libavformat/mmsh.c @@ -249,7 +249,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) 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; } @@ -296,7 +296,7 @@ static int mmsh_open(URLContext *h, const char *uri, int flags) 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 e69d330e1b..7bb4358060 100644 --- a/libavformat/mmst.c +++ b/libavformat/mmst.c @@ -524,7 +524,7 @@ 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, - &h->interrupt_callback); + &h->interrupt_callback, NULL); if (err) goto fail; diff --git a/libavformat/rtmpproto.c b/libavformat/rtmpproto.c index 98e6180c92..9d734072ab 100644 --- a/libavformat/rtmpproto.c +++ b/libavformat/rtmpproto.c @@ -818,7 +818,7 @@ static int rtmp_open(URLContext *s, const char *uri, int flags) ff_url_join(buf, sizeof(buf), "tcp", NULL, hostname, port, NULL); if (ffurl_open(&rt->stream, buf, AVIO_FLAG_READ_WRITE, - &s->interrupt_callback) < 0) { + &s->interrupt_callback, NULL) < 0) { av_log(s , AV_LOG_ERROR, "Cannot open connection %s\n", buf); goto fail; } diff --git a/libavformat/rtpproto.c b/libavformat/rtpproto.c index ca5007667a..9707bdcec7 100644 --- a/libavformat/rtpproto.c +++ b/libavformat/rtpproto.c @@ -188,7 +188,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, &h->interrupt_callback) < 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; @@ -196,7 +196,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, &h->interrupt_callback) < 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 diff --git a/libavformat/rtsp.c b/libavformat/rtsp.c index d07cd406ed..d0e9bbf6af 100644 --- a/libavformat/rtsp.c +++ b/libavformat/rtsp.c @@ -1160,7 +1160,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, /* 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, - &s->interrupt_callback) == 0) + &s->interrupt_callback, NULL) == 0) goto rtp_opened; } } @@ -1308,7 +1308,7 @@ int ff_rtsp_make_setup_request(AVFormatContext *s, const char *host, int port, 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, - &s->interrupt_callback) < 0) { + &s->interrupt_callback, NULL) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1468,7 +1468,7 @@ 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; } @@ -1511,7 +1511,7 @@ 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; } @@ -1519,7 +1519,7 @@ redirect: /* 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, - &s->interrupt_callback) < 0) { + &s->interrupt_callback, NULL) < 0) { err = AVERROR(EIO); goto fail; } @@ -1868,7 +1868,7 @@ static int sdp_read_header(AVFormatContext *s, AVFormatParameters *ap) 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, - &s->interrupt_callback) < 0) { + &s->interrupt_callback, NULL) < 0) { err = AVERROR_INVALIDDATA; goto fail; } @@ -1933,7 +1933,7 @@ static int rtp_read_header(AVFormatContext *s, return AVERROR(EIO); ret = ffurl_open(&in, s->filename, AVIO_FLAG_READ, - &s->interrupt_callback); + &s->interrupt_callback, NULL); if (ret) goto fail; diff --git a/libavformat/sapdec.c b/libavformat/sapdec.c index 7b950cd617..6ac7bfd484 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, &s->interrupt_callback); + ret = ffurl_open(&sap->ann_fd, url, AVIO_FLAG_READ, + &s->interrupt_callback, NULL); if (ret) goto fail; diff --git a/libavformat/sapenc.c b/libavformat/sapenc.c index ec017909eb..d8ec465afa 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, &s->interrupt_callback); + 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, &s->interrupt_callback); + 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/tls.c b/libavformat/tls.c index b2ec147adb..33ee782fa8 100644 --- a/libavformat/tls.c +++ b/libavformat/tls.c @@ -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, &h->interrupt_callback); + 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 902539aa64..1f04c8d530 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -28,6 +28,8 @@ #include "avio.h" #include "libavformat/version.h" +#include "libavutil/dict.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 */ @@ -48,6 +50,12 @@ typedef struct 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); @@ -82,8 +90,13 @@ int ffurl_alloc(URLContext **puc, const char *filename, int flags, /** * 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 @@ -95,11 +108,14 @@ int ffurl_connect(URLContext *uc); * 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, - const AVIOInterruptCB *int_cb); + const AVIOInterruptCB *int_cb, AVDictionary **options); /** * Read up to size bytes from the resource accessed by h, and store From 1dee0aca7401fc6c01f23ceedaff6533efb0fb28 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 23:03:45 +0200 Subject: [PATCH 11/13] avio: add avio_open2, taking an interrupt callback and options The interrupt callback has to be passed in during opening (setting it after opening isn't enough), since a blocking open couldn't be interrupted otherwise. Options are passed down to procotols and also need to be available during open() in most cases. Signed-off-by: Anton Khirnov --- libavformat/avio.c | 4 ++-- libavformat/avio.h | 36 ++++++++++++++++++++++++++++++++++ libavformat/avio_internal.h | 4 ++++ libavformat/aviobuf.c | 39 ++++++++++++++++++++++++++++++++++++- libavformat/url.h | 3 +++ 5 files changed, 83 insertions(+), 3 deletions(-) diff --git a/libavformat/avio.c b/libavformat/avio.c index 330d52cfec..9de435e073 100644 --- a/libavformat/avio.c +++ b/libavformat/avio.c @@ -73,7 +73,7 @@ static const AVClass *urlcontext_child_class_next(const AVClass *prev) } 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, @@ -135,7 +135,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; diff --git a/libavformat/avio.h b/libavformat/avio.h index a4041cb770..b665bb3b3b 100644 --- a/libavformat/avio.h +++ b/libavformat/avio.h @@ -28,6 +28,7 @@ #include #include "libavutil/common.h" +#include "libavutil/dict.h" #include "libavutil/log.h" #include "libavformat/version.h" @@ -64,6 +65,21 @@ typedef struct { * 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 */ @@ -573,6 +589,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 1369c43891..f2ccc36623 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 246903baac..898f35d903 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); @@ -856,6 +884,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; } @@ -928,11 +959,17 @@ 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, NULL, NULL); + err = ffurl_open(&h, filename, flags, int_cb, options); if (err < 0) return err; err = ffio_fdopen(s, h); diff --git a/libavformat/url.h b/libavformat/url.h index 1f04c8d530..ea8c7abb8f 100644 --- a/libavformat/url.h +++ b/libavformat/url.h @@ -29,12 +29,15 @@ #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; From 9d77a8faf9568f02daf06903559473efb4050c34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Martin=20Storsj=C3=B6?= Date: Sun, 6 Nov 2011 23:11:29 +0200 Subject: [PATCH 12/13] avformat: Use avio_open2, pass the AVFormatContext interrupt_callback onwards Signed-off-by: Anton Khirnov --- libavformat/applehttp.c | 3 ++- libavformat/applehttpproto.c | 3 ++- libavformat/img2.c | 6 ++++-- libavformat/mov.c | 7 ++++--- libavformat/utils.c | 3 ++- 5 files changed, 14 insertions(+), 8 deletions(-) diff --git a/libavformat/applehttp.c b/libavformat/applehttp.c index 74d9f781e3..e0773ae87f 100644 --- a/libavformat/applehttp.c +++ b/libavformat/applehttp.c @@ -210,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; } diff --git a/libavformat/applehttpproto.c b/libavformat/applehttpproto.c index 2123423452..0e64dadb39 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)); diff --git a/libavformat/img2.c b/libavformat/img2.c index 25c3f7656a..547f23fe0a 100644 --- a/libavformat/img2.c +++ b/libavformat/img2.c @@ -304,7 +304,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); @@ -388,7 +389,8 @@ static int write_packet(AVFormatContext *s, AVPacket *pkt) return AVERROR(EIO); } 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/mov.c b/libavformat/mov.c index 351058c968..ced60cbbb7 100644 --- a/libavformat/mov.c +++ b/libavformat/mov.c @@ -1770,7 +1770,8 @@ static void mov_build_index(MOVContext *mov, AVStream *st) } } -static int mov_open_dref(AVIOContext **pb, char *src, MOVDref *ref) +static int mov_open_dref(AVIOContext **pb, 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 */ @@ -1805,7 +1806,7 @@ static int mov_open_dref(AVIOContext **pb, 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; } } @@ -1860,7 +1861,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/utils.c b/libavformat/utils.c index 91760c89ab..399b709961 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -593,7 +593,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, NULL)) < 0) return ret; if (s->iformat) return 0; From 32caa7b13cecca59213c73fa94dd683c2b003bfd Mon Sep 17 00:00:00 2001 From: Anton Khirnov Date: Sat, 5 Nov 2011 12:30:21 +0100 Subject: [PATCH 13/13] lavf: pass options from AVFormatContext to avio. --- libavformat/options.c | 17 ++++++++++++++--- libavformat/utils.c | 6 +++--- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/libavformat/options.c b/libavformat/options.c index 23a7e65369..66e01a4082 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; } @@ -59,9 +64,15 @@ static const AVClass *format_child_class_next(const AVClass *prev) while (prev && (ofmt = av_oformat_next(ofmt))) if (ofmt->priv_class == prev) break; - while (ofmt = av_oformat_next(ofmt)) - if (ofmt->priv_class) - return ofmt->priv_class; + if ((prev && ofmt) || (!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/utils.c b/libavformat/utils.c index 399b709961..2dc7623dff 100644 --- a/libavformat/utils.c +++ b/libavformat/utils.c @@ -575,7 +575,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}; @@ -594,7 +594,7 @@ static int init_input(AVFormatContext *s, const char *filename) return 0; if ((ret = avio_open2(&s->pb, filename, AVIO_FLAG_READ, - &s->interrupt_callback, NULL)) < 0) + &s->interrupt_callback, options)) < 0) return ret; if (s->iformat) return 0; @@ -619,7 +619,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 */