[FFmpeg-cvslog] avio: add support for passing options to protocols.

Anton Khirnov git at videolan.org
Mon Nov 14 00:43:07 CET 2011


ffmpeg | branch: master | Anton Khirnov <anton at khirnov.net> | Sat Nov  5 10:04:04 2011 +0100| [ddffc2fdc351d60ca190b016cccff4acff27823f] | committer: Anton Khirnov

avio: add support for passing options to protocols.

Not used anywhere yet, support for passing options from avio_open() will
follow.

> http://git.videolan.org/gitweb.cgi/ffmpeg.git/?a=commit;h=ddffc2fdc351d60ca190b016cccff4acff27823f
---

 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 ae25153..74d9f78 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 e8d1b49..2123423 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 06972cd..330d52c 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"
@@ -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 b2bd6f8..246903b 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 47f97ef..1501cbc 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 5171b12..7095360 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 afb0aff..5f8c320 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 dbf384e..9cc55bd 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 f136e80..8e61e5b 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 6ea1592..50e160f 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 e69d330..7bb4358 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 98e6180..9d73407 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 ca50076..9707bdc 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 d07cd40..d0e9bbf 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 7b950cd..6ac7bfd 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 ec01790..d8ec465 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 b2ec147..33ee782 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 902539a..1f04c8d 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



More information about the ffmpeg-cvslog mailing list