]> git.sesse.net Git - vlc/blobdiff - modules/access/rtp/input.c
Use var_Inherit* instead of var_CreateGet*.
[vlc] / modules / access / rtp / input.c
index ccd48b9338e2f411e6cd8af6c70d8e66b8b11327..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.
  * @param fd datagram file descriptor
  * @return a block or NULL on fatal error (socket dead)
  */
-static block_t *rtp_dgram_recv (int fd)
+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
     {
-        struct pollfd ufd = { .fd = fd, .events = POLLIN, };
-
-        block_cleanup_push (block);
-        poll (&ufd, 1, -1);
-        len = recv (fd, block->p_buffer, block->i_buffer, 0);
-        vlc_cleanup_pop ();
+        len = net_Read (obj, fd, NULL,
+                        block->p_buffer, block->i_buffer, false);
 
-        if ((len <= 0) && (ufd.revents & POLLHUP))
+        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;
 }
 
 
@@ -73,19 +80,15 @@ static block_t *rtp_dgram_recv (int fd)
  * @param fd stream file descriptor
  * @return a block or NULL in case of fatal error
  */
-static block_t *rtp_stream_recv (int fd)
+static block_t *rtp_stream_recv (vlc_object_t *obj, int fd)
 {
     ssize_t len = 0;
-    struct pollfd ufd = { .fd = fd, .events = POLLIN, };
     uint8_t hdr[2]; /* frame header */
 
     /* Receives the RTP frame header */
     do
     {
-        ssize_t val;
-
-        poll (&ufd, 1, -1);
-        val = recv (fd, hdr + len, 2 - len, 0);
+        ssize_t val = net_Read (obj, fd, NULL, hdr + len, 2 - len, false);
         if (val <= 0)
             return NULL;
         len += val;
@@ -100,8 +103,8 @@ static block_t *rtp_stream_recv (int fd)
         ssize_t val;
 
         block_cleanup_push (block);
-        poll (&ufd, 1, -1);
-        val = recv (fd, block->p_buffer + i, block->i_buffer - i, 0);
+        val = net_Read (obj, fd, NULL,
+                        block->p_buffer + i, block->i_buffer - i, false);
         vlc_cleanup_pop ();
 
         if (val <= 0)
@@ -123,8 +126,8 @@ static block_t *rtp_recv (demux_t *demux)
     for (block_t *block;; block_Release (block))
     {
         block = p_sys->framed_rtp
-                ? rtp_stream_recv (p_sys->fd)
-                : rtp_dgram_recv (p_sys->fd);
+                ? rtp_stream_recv (VLC_OBJECT (demux), p_sys->fd)
+                : rtp_dgram_recv (VLC_OBJECT (demux), p_sys->fd);
         if (block == NULL)
         {
             msg_Err (demux, "RTP flow stopped");
@@ -138,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;
@@ -154,54 +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;
+
+    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);
         if (block == NULL)
-            break; /* fatal error: abort */
+            break;
 
-        vlc_mutex_lock (&p_sys->lock);
-
-        /* Autodetect payload type, _before_ rtp_queue() */
-        if (p_sys->autodetect)
-        {
+        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;
             }
-            p_sys->autodetect = false;
+            autodetect = false;
         }
 
+        int canc = vlc_savecancel ();
+        vlc_mutex_lock (&p_sys->lock);
         rtp_queue (demux, p_sys->session, block);
-        vlc_cond_signal (&p_sys->wait);
         vlc_mutex_unlock (&p_sys->lock);
+        vlc_restorecancel (canc);
+
+        rtp_process (demux);
     }
-    /* TODO: return 0 from 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;
 
     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);
 }
-