]> git.sesse.net Git - vlc/blobdiff - modules/access/rtp/input.c
Use var_InheritString for --decklink-video-connection.
[vlc] / modules / access / rtp / input.c
index dc1110b149fa70fd2a7035e6220eb7d644af1217..15d62e1ee5253921ac64f4f0723d57ac85f0c4ea 100644 (file)
@@ -6,8 +6,8 @@
  * Copyright © 2008 Rémi Denis-Courmont
  *
  * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2.0
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 2.1
  * of the License, or (at your option) any later version.
  *
  * This library is distributed in the hope that it will be useful,
 #endif
 
 #include "rtp.h"
-#include <srtp.h>
+#ifdef HAVE_SRTP
+# include <srtp.h>
+#endif
+
+static bool fd_dead (int fd)
+{
+    struct pollfd ufd = { .fd = fd, };
+    return (poll (&ufd, 1, 0) > 0) && (ufd.revents & POLLHUP);
+}
 
 /**
  * Gets a datagram from the network.
@@ -47,23 +55,23 @@ static block_t *rtp_dgram_recv (vlc_object_t *obj, int fd)
     block_t *block = block_Alloc (0xffff);
     ssize_t len;
 
+    block_cleanup_push (block);
     do
     {
-        block_cleanup_push (block);
         len = net_Read (obj, fd, NULL,
                         block->p_buffer, block->i_buffer, false);
-        vlc_cleanup_pop ();
 
-        if (((len <= 0) && poll (&(struct pollfd){ .fd = fd, }, 1, 0))
-         || !vlc_object_alive (obj))
+        if (((len <= 0) && fd_dead (fd)) || !vlc_object_alive (obj))
         {   /* POLLHUP -> permanent (DCCP) socket error */
             block_Release (block);
-            return NULL;
+            block = NULL;
+            break;
         }
     }
     while (len == -1);
+    vlc_cleanup_pop ();
 
-    return block_Realloc (block, 0, len);
+    return block ? block_Realloc (block, 0, len) : NULL;
 }
 
 
@@ -133,7 +141,7 @@ static block_t *rtp_recv (demux_t *demux)
         const uint8_t ptype = rtp_ptype (block);
         if (ptype >= 72 && ptype <= 76)
             continue; /* Muxed RTCP, ignore for now */
-
+#ifdef HAVE_SRTP
         if (p_sys->srtp)
         {
             size_t len = block->i_buffer;
@@ -149,56 +157,71 @@ static block_t *rtp_recv (demux_t *demux)
             }
             block->i_buffer = len;
         }
+#endif
         return block; /* success! */
     }
     return NULL;
 }
 
 
+static void timer_cleanup (void *timer)
+{
+    vlc_timer_destroy ((vlc_timer_t)timer);
+}
+
+static void rtp_process (void *data);
+
 void *rtp_thread (void *data)
 {
     demux_t *demux = data;
     demux_sys_t *p_sys = demux->p_sys;
+    bool autodetect = true;
 
-    do
+    if (vlc_timer_create (&p_sys->timer, rtp_process, data))
+        return NULL;
+    vlc_cleanup_push (timer_cleanup, (void *)p_sys->timer);
+
+    for (;;)
     {
         block_t *block = rtp_recv (demux);
-
-        vlc_mutex_lock (&p_sys->lock);
         if (block == NULL)
-            p_sys->dead = true; /* Fatal error: abort */
-        else
-        {
-            if (p_sys->autodetect)
-            {   /* Autodetect payload type, _before_ rtp_queue() */
-                if (rtp_autodetect (demux, p_sys->session, block))
-                {
-                    vlc_mutex_unlock (&p_sys->lock);
-                    block_Release (block);
-                    continue;
-                }
-                p_sys->autodetect = false;
+            break;
+
+        if (autodetect)
+        {   /* Autodetect payload type, _before_ rtp_queue() */
+            /* No need for lock - the queue is empty. */
+            if (rtp_autodetect (demux, p_sys->session, block))
+            {
+                block_Release (block);
+                continue;
             }
-            rtp_queue (demux, p_sys->session, block);
+            autodetect = false;
         }
-        vlc_cond_signal (&p_sys->wait);
+
+        int canc = vlc_savecancel ();
+        vlc_mutex_lock (&p_sys->lock);
+        rtp_queue (demux, p_sys->session, block);
         vlc_mutex_unlock (&p_sys->lock);
-    }
-    while (!p_sys->dead);
+        vlc_restorecancel (canc);
 
+        rtp_process (demux);
+    }
+    vlc_cleanup_run ();
     return NULL;
 }
 
 
-void rtp_process (demux_t *demux)
+/**
+ * Process one RTP packet from the de-jitter queue.
+ */
+static void rtp_process (void *data)
 {
+    demux_t *demux = data;
     demux_sys_t *p_sys = demux->p_sys;
-    mtime_t deadline = INT64_MAX;
+    mtime_t deadline;
 
     vlc_mutex_lock (&p_sys->lock);
-    if (!rtp_dequeue (demux, p_sys->session, &deadline))
-        deadline = mdate () + CLOCK_FREQ / 5;
-    vlc_cond_timedwait (&p_sys->wait, &p_sys->lock, deadline);
+    if (rtp_dequeue (demux, p_sys->session, &deadline))
+        vlc_timer_schedule (p_sys->timer, true, deadline, 0);
     vlc_mutex_unlock (&p_sys->lock);
 }
-