rtp: Map the urloptions to AVOptions
authorLuca Barbato <lu_zero@gentoo.org>
Sun, 22 Mar 2015 17:08:43 +0000 (18:08 +0100)
committerLuca Barbato <lu_zero@gentoo.org>
Wed, 1 Apr 2015 12:26:35 +0000 (14:26 +0200)
Signed-off-by: Luca Barbato <lu_zero@gentoo.org>
libavformat/rtpproto.c

index 5bff00e..2e83bbb 100644 (file)
@@ -26,6 +26,7 @@
 
 #include "libavutil/parseutils.h"
 #include "libavutil/avstring.h"
+#include "libavutil/opt.h"
 #include "avformat.h"
 #include "avio_internal.h"
 #include "rtp.h"
 #endif
 
 typedef struct RTPContext {
+    const AVClass *class;
     URLContext *rtp_hd, *rtcp_hd;
     int rtp_fd, rtcp_fd, nb_ssm_include_addrs, nb_ssm_exclude_addrs;
     struct sockaddr_storage **ssm_include_addrs, **ssm_exclude_addrs;
     int write_to_source;
     struct sockaddr_storage last_rtp_source, last_rtcp_source;
     socklen_t last_rtp_source_len, last_rtcp_source_len;
+    int ttl;
+    int rtcp_port, local_rtpport, local_rtcpport;
+    int connect;
+    int pkt_size;
+    char *sources;
+    char *block;
 } RTPContext;
 
+#define OFFSET(x) offsetof(RTPContext, x)
+#define D AV_OPT_FLAG_DECODING_PARAM
+#define E AV_OPT_FLAG_ENCODING_PARAM
+static const AVOption options[] = {
+    { "ttl",                "Time to live (in milliseconds, multicast only)",                   OFFSET(ttl),             AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
+    { "rtcp_port",          "Custom rtcp port",                                                 OFFSET(rtcp_port),       AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
+    { "local_rtpport",      "Local rtp port",                                                   OFFSET(local_rtpport),   AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
+    { "local_rtcpport",     "Local rtcp port",                                                  OFFSET(local_rtcpport),  AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
+    { "connect",            "Connect socket",                                                   OFFSET(connect),         AV_OPT_TYPE_INT,    { .i64 =  0 },     0, 1,       .flags = D|E },
+    { "write_to_source",    "Send packets to the source address of the latest received packet", OFFSET(write_to_source), AV_OPT_TYPE_INT,    { .i64 =  0 },     0, 1,       .flags = D|E },
+    { "pkt_size",           "Maximum packet size",                                              OFFSET(pkt_size),        AV_OPT_TYPE_INT,    { .i64 = -1 },    -1, INT_MAX, .flags = D|E },
+    { "sources",            "Source list",                                                      OFFSET(sources),         AV_OPT_TYPE_STRING, { .str = NULL },               .flags = D|E },
+    { "block",              "Block list",                                                       OFFSET(block),           AV_OPT_TYPE_STRING, { .str = NULL },               .flags = D|E },
+    { NULL }
+};
+
+static const AVClass rtp_class = {
+    .class_name = "rtp",
+    .item_name  = av_default_item_name,
+    .option     = options,
+    .version    = LIBAVUTIL_VERSION_INT,
+};
+
 /**
  * If no filename is given to av_open_input_file because you want to
  * get the local port first, then you must call this function to set
@@ -188,21 +219,21 @@ static av_printf_format(3, 4) void url_add_option(char *buf, int buf_size, const
     va_end(ap);
 }
 
-static void build_udp_url(char *buf, int buf_size,
-                          const char *hostname, int port,
-                          int local_port, int ttl,
-                          int max_packet_size, int connect,
+static void build_udp_url(RTPContext *s,
+                          char *buf, int buf_size,
+                          const char *hostname,
+                          int port, int local_port,
                           const char *include_sources,
                           const char *exclude_sources)
 {
     ff_url_join(buf, buf_size, "udp", NULL, hostname, port, NULL);
     if (local_port >= 0)
         url_add_option(buf, buf_size, "localport=%d", local_port);
-    if (ttl >= 0)
-        url_add_option(buf, buf_size, "ttl=%d", ttl);
-    if (max_packet_size >=0)
-        url_add_option(buf, buf_size, "pkt_size=%d", max_packet_size);
-    if (connect)
+    if (s->ttl >= 0)
+        url_add_option(buf, buf_size, "ttl=%d", s->ttl);
+    if (s->pkt_size >= 0)
+        url_add_option(buf, buf_size, "pkt_size=%d", s->pkt_size);
+    if (s->connect)
         url_add_option(buf, buf_size, "connect=1");
     if (include_sources && include_sources[0])
         url_add_option(buf, buf_size, "sources=%s", include_sources);
@@ -275,10 +306,9 @@ static void rtp_parse_addr_list(URLContext *h, char *buf,
 static int rtp_open(URLContext *h, const char *uri, int flags)
 {
     RTPContext *s = h->priv_data;
-    int rtp_port, rtcp_port,
-        ttl, connect,
-        local_rtp_port, local_rtcp_port, max_packet_size;
+    int rtp_port;
     char hostname[256], include_sources[1024] = "", exclude_sources[1024] = "";
+    char *sources = include_sources, *block = exclude_sources;
     char buf[1024];
     char path[1024];
     const char *p;
@@ -286,60 +316,61 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
     av_url_split(NULL, 0, NULL, 0, hostname, sizeof(hostname), &rtp_port,
                  path, sizeof(path), uri);
     /* extract parameters */
-    ttl = -1;
-    rtcp_port = rtp_port+1;
-    local_rtp_port = -1;
-    local_rtcp_port = -1;
-    max_packet_size = -1;
-    connect = 0;
+    if (s->rtcp_port < 0)
+        s->rtcp_port = rtp_port + 1;
 
     p = strchr(uri, '?');
     if (p) {
         if (av_find_info_tag(buf, sizeof(buf), "ttl", p)) {
-            ttl = strtol(buf, NULL, 10);
+            s->ttl = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "rtcpport", p)) {
-            rtcp_port = strtol(buf, NULL, 10);
+            s->rtcp_port = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "localport", p)) {
-            local_rtp_port = strtol(buf, NULL, 10);
+            s->local_rtpport = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "localrtpport", p)) {
-            local_rtp_port = strtol(buf, NULL, 10);
+            s->local_rtpport = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "localrtcpport", p)) {
-            local_rtcp_port = strtol(buf, NULL, 10);
+            s->local_rtcpport = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "pkt_size", p)) {
-            max_packet_size = strtol(buf, NULL, 10);
+            s->pkt_size = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "connect", p)) {
-            connect = strtol(buf, NULL, 10);
+            s->connect = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "write_to_source", p)) {
             s->write_to_source = strtol(buf, NULL, 10);
         }
         if (av_find_info_tag(buf, sizeof(buf), "sources", p)) {
             av_strlcpy(include_sources, buf, sizeof(include_sources));
+
             rtp_parse_addr_list(h, buf, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
+        } else {
+            rtp_parse_addr_list(h, s->sources, &s->ssm_include_addrs, &s->nb_ssm_include_addrs);
+            sources = s->sources;
         }
         if (av_find_info_tag(buf, sizeof(buf), "block", p)) {
             av_strlcpy(exclude_sources, buf, sizeof(exclude_sources));
             rtp_parse_addr_list(h, buf, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
+        } else {
+            rtp_parse_addr_list(h, s->block, &s->ssm_exclude_addrs, &s->nb_ssm_exclude_addrs);
+            block = s->block;
         }
     }
 
-    build_udp_url(buf, sizeof(buf),
-                  hostname, rtp_port, local_rtp_port, ttl, max_packet_size,
-                  connect, include_sources, exclude_sources);
+    build_udp_url(s, buf, sizeof(buf),
+                  hostname, rtp_port, s->local_rtpport, sources, block);
     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;
+    if (s->local_rtpport >= 0 && s->local_rtcpport < 0)
+        s->local_rtcpport = ff_udp_get_local_port(s->rtp_hd) + 1;
 
-    build_udp_url(buf, sizeof(buf),
-                  hostname, rtcp_port, local_rtcp_port, ttl, max_packet_size,
-                  connect, include_sources, exclude_sources);
+    build_udp_url(s, buf, sizeof(buf),
+                  hostname, s->rtcp_port, s->local_rtcpport, sources, block);
     if (ffurl_open(&s->rtcp_hd, buf, flags, &h->interrupt_callback, NULL) < 0)
         goto fail;
 
@@ -548,4 +579,5 @@ URLProtocol ff_rtp_protocol = {
     .url_get_multi_file_handle = rtp_get_multi_file_handle,
     .priv_data_size            = sizeof(RTPContext),
     .flags                     = URL_PROTOCOL_FLAG_NETWORK,
+    .priv_data_class           = &rtp_class,
 };