[vlc-commits] access_output: rist: add support for multicast

Sergio Ammirata git at videolan.org
Wed Mar 20 15:22:52 CET 2019


vlc | branch: master | Sergio Ammirata <sergio at ammirata.net> | Tue Mar 19 08:15:07 2019 -0400| [f2ed24657adc5e379e326dbba3ca8541291ed425] | committer: Thomas Guillem

access_output: rist: add support for multicast

Signed-off-by: Thomas Guillem <thomas at gllm.fr>

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

 modules/access_output/rist.c | 108 +++++++++++++++++++++++++++++++++++--------
 1 file changed, 88 insertions(+), 20 deletions(-)

diff --git a/modules/access_output/rist.c b/modules/access_output/rist.c
index 5ce799b14e..3f2f3901bd 100644
--- a/modules/access_output/rist.c
+++ b/modules/access_output/rist.c
@@ -72,6 +72,7 @@ static const char *const ppsz_sout_options[] = {
     "caching",
     "buffer-size",
     "ssrc",
+    "stream-name",
     NULL
 };
 
@@ -85,6 +86,7 @@ typedef struct
     vlc_thread_t senderthread;
     size_t       i_packet_size;
     bool         b_mtu_warning;
+    bool         b_ismulticast;
     vlc_mutex_t  lock;
     vlc_mutex_t  fd_lock;
     block_t      *p_pktbuffer;
@@ -112,12 +114,13 @@ static struct rist_flow *rist_init_tx()
     }
     flow->fd_out = -1;
     flow->fd_rtcp = -1;
+    flow->fd_rtcp_m = -1;
 
     return flow;
 }
 
 static struct rist_flow *rist_udp_transmitter(sout_access_out_t *p_access, char *psz_dst_server, 
-    int i_dst_port)
+    int i_dst_port, bool b_ismulticast)
 {
     struct rist_flow *flow;
     flow = rist_init_tx();
@@ -131,6 +134,16 @@ static struct rist_flow *rist_udp_transmitter(sout_access_out_t *p_access, char
         goto fail;
     }
 
+    if (b_ismulticast) {
+        flow->fd_rtcp_m = net_OpenDgram(p_access, psz_dst_server, i_dst_port + 1,
+            NULL, 0, IPPROTO_UDP);
+        if (flow->fd_rtcp_m < 0)
+        {
+            msg_Err( p_access, "cannot open multicast nack socket" );
+            goto fail;
+        }
+    }
+
     flow->fd_rtcp = net_ConnectDgram(p_access, psz_dst_server, i_dst_port + 1, -1, IPPROTO_UDP );
     if (flow->fd_rtcp < 0)
     {
@@ -138,7 +151,18 @@ static struct rist_flow *rist_udp_transmitter(sout_access_out_t *p_access, char
         goto fail;
     }
 
-    populate_cname(flow->fd_rtcp, flow->cname);
+    char *psz_streamname = NULL;
+    psz_streamname = var_InheritString( p_access, SOUT_CFG_PREFIX "stream-name" );
+    if ( psz_streamname != NULL && psz_streamname[0] != '\0')
+    {
+        int name_length = snprintf(flow->cname, MAX_CNAME, "%s", psz_streamname);
+        if (name_length >= MAX_CNAME)
+            flow->cname[MAX_CNAME-1] = 0;
+        free( psz_streamname );
+    }
+    else
+        populate_cname(flow->fd_rtcp, flow->cname);
+
     msg_Info(p_access, "our cname is %s", flow->cname);
 
     return flow;
@@ -148,6 +172,8 @@ fail:
         vlc_close(flow->fd_out);
     if (flow->fd_rtcp != -1)
         vlc_close(flow->fd_rtcp);
+    if (flow->fd_rtcp_m != -1)
+        vlc_close(flow->fd_rtcp_m);
     free(flow->buffer);
     free(flow);
     return NULL;
@@ -188,6 +214,7 @@ static void rist_retransmit(sout_access_out_t *p_access, struct rist_flow *flow,
                 != (ssize_t)pkt->buffer->i_buffer) {
             msg_Err(p_access, "Error sending retransmitted packet after 2 tries ...");
         }
+
         vlc_mutex_unlock( &p_sys->fd_lock );
     }
 }
@@ -298,23 +325,29 @@ static void rist_rtcp_recv(sout_access_out_t *p_access, struct rist_flow *flow,
                 break;
 
             case RTCP_PT_RR:
-                /*process_rr(f, pkt, len);*/
+                /*
+                if (p_sys->b_ismulticast == false)
+                    process_rr(f, pkt, len);
+                */
                 break;
 
             case RTCP_PT_SDES:
                 {
-                    int8_t name_length = rtcp_sdes_get_name_length(pkt);
-                    if (name_length > bytes_left)
-                    {
-                        /* check for a sane number of bytes */
-                        msg_Err(p_access, "Malformed SDES packet, wrong cname len %u, got a " \
-                            "buffer of %u bytes.", name_length, bytes_left);
-                        return;
-                    }
-                    if (memcmp(pkt + RTCP_SDES_SIZE, p_sys->receiver_name, name_length) != 0)
+                    if (p_sys->b_ismulticast == false)
                     {
-                        memcpy(p_sys->receiver_name, pkt + RTCP_SDES_SIZE, name_length);
-                        msg_Info(p_access, "Receiver name: %s", p_sys->receiver_name);
+                        int8_t name_length = rtcp_sdes_get_name_length(pkt);
+                        if (name_length > bytes_left)
+                        {
+                            /* check for a sane number of bytes */
+                            msg_Err(p_access, "Malformed SDES packet, wrong cname len %u, got a " \
+                                "buffer of %u bytes.", name_length, bytes_left);
+                            return;
+                        }
+                        if (memcmp(pkt + RTCP_SDES_SIZE, p_sys->receiver_name, name_length) != 0)
+                        {
+                            memcpy(p_sys->receiver_name, pkt + RTCP_SDES_SIZE, name_length);
+                            msg_Info(p_access, "Receiver name: %s", p_sys->receiver_name);
+                        }
                     }
                 }
                 break;
@@ -382,15 +415,22 @@ static void *rist_thread(void *data)
     sout_access_out_sys_t *p_sys = p_access->p_sys;
     uint64_t now;
     uint8_t pkt[RTP_PKT_SIZE];
-    struct pollfd pfd[1];
+    struct pollfd pfd[2];
     int ret;
     ssize_t r;
 
+    int poll_sockets = 1;
     pfd[0].fd = p_sys->flow->fd_rtcp;
     pfd[0].events = POLLIN;
+    if (p_sys->b_ismulticast)
+    {
+        pfd[1].fd = p_sys->flow->fd_rtcp_m;
+        pfd[1].events = POLLIN;
+        poll_sockets++;
+    }
 
     for (;;) {
-        ret = poll(pfd, 1, RTCP_INTERVAL >> 1);
+        ret = poll(pfd, poll_sockets, RTCP_INTERVAL >> 1);
         int canc = vlc_savecancel();
         if (ret > 0)
         {
@@ -409,6 +449,21 @@ static void *rist_thread(void *data)
                     rist_rtcp_recv(p_access, p_sys->flow, pkt, r);
                 }
             }
+            if (p_sys->b_ismulticast && (pfd[1].revents & POLLIN))
+            {
+                r = rist_Read(p_sys->flow->fd_rtcp_m, pkt, RTP_PKT_SIZE);
+                if (r == RTP_PKT_SIZE) {
+                    msg_Err(p_access, "Rist RTCP messsage is too big (%zd bytes) and was " \
+                        "probably cut, please keep it under %d bytes", r, RTP_PKT_SIZE);
+                }
+                if (unlikely(r == -1)) {
+                    msg_Err(p_access, "mcast socket %d error: %s\n", p_sys->flow->fd_rtcp_m,
+                        gai_strerror(errno));
+                }
+                else {
+                    rist_rtcp_recv(p_access, p_sys->flow, pkt, r);
+                }
+            }
         }
 
         /* And, in any case: */
@@ -457,8 +512,11 @@ static void* ThreadSend( void *data )
         if ((seq % 14) == 0) {
             /*msg_Err(p_access, "Dropped packet with seq number %d ...", seq);*/
         }
-        else if (rist_Write(flow->fd_out, out->p_buffer, len) != len) {
-            msg_Err(p_access, "Error sending data packet after 2 tries ...");
+        else
+        {
+            if (rist_Write(flow->fd_out, out->p_buffer, len) != len) {
+                msg_Err(p_access, "Error sending data packet after 2 tries ...");
+            }
         }
 #else
         if (rist_Write(flow->fd_out, out->p_buffer, len) != len) {
@@ -638,9 +696,12 @@ static void Clean( sout_access_out_t *p_access )
         if (p_sys->flow->fd_out >= 0) {
             net_Close (p_sys->flow->fd_out);
         }
-        if (p_sys->flow->fd_nack >= 0) {
+        if (p_sys->flow->fd_rtcp >= 0) {
             net_Close (p_sys->flow->fd_rtcp);
         }
+        if (p_sys->flow->fd_rtcp_m >= 0) {
+            net_Close (p_sys->flow->fd_rtcp_m);
+        }
         for (int i=0; i<RIST_QUEUE_SIZE; i++) {
             struct rtp_pkt *pkt = &(p_sys->flow->buffer[i]);
             if (pkt->buffer)
@@ -714,7 +775,9 @@ static int Open( vlc_object_t *p_this )
 
     msg_Info(p_access, "Connecting RIST output to %s:%d and %s:%d", psz_dst_addr, i_dst_port, 
         psz_dst_addr, i_dst_port+1);
-    struct rist_flow *flow = rist_udp_transmitter(p_access, psz_dst_addr, i_dst_port);
+    p_sys->b_ismulticast = is_multicast_address(psz_dst_addr);
+    struct rist_flow *flow = rist_udp_transmitter(p_access, psz_dst_addr, i_dst_port,
+        p_sys->b_ismulticast);
     free (psz_dst_addr);
     if (!flow)
         goto failed;
@@ -786,6 +849,10 @@ failed:
     "Use this setting to specify a known SSRC for the RTP header. This is only useful " \
     "if your receiver acts on it. When using VLC as receiver, it is not." )
 
+#define NAME_TEXT N_("Stream name")
+#define NAME_LONGTEXT N_( \
+    "This Stream name will be sent to the receiver using the rist RTCP channel" )
+
 /* Module descriptor */
 vlc_module_begin()
 
@@ -802,6 +869,7 @@ vlc_module_begin()
             BUFFER_TEXT, BUFFER_LONGTEXT, true )
     add_integer( SOUT_CFG_PREFIX "ssrc", 0,
             SSRC_TEXT, SSRC_LONGTEXT, true )
+    add_string( SOUT_CFG_PREFIX "stream-name", NULL, NAME_TEXT, NAME_LONGTEXT, true )
 
     set_capability( "sout access", 0 )
     add_shortcut( "rist", "tr06" )



More information about the vlc-commits mailing list