* 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.
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;
}
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;
}
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);
}
-