3 * @brief RTP packet input
5 /*****************************************************************************
6 * Copyright © 2008 Rémi Denis-Courmont
8 * This library is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public License
10 * as published by the Free Software Foundation; either version 2.1
11 * of the License, or (at your option) any later version.
13 * This library is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 ****************************************************************************/
27 #include <vlc_common.h>
28 #include <vlc_demux.h>
29 #include <vlc_block.h>
30 #include <vlc_network.h>
45 * Processes a packet received from the RTP socket.
47 static void rtp_process (demux_t *demux, block_t *block)
49 demux_sys_t *sys = demux->p_sys;
51 if (block->i_buffer < 2)
53 const uint8_t ptype = rtp_ptype (block);
54 if (ptype >= 72 && ptype <= 76)
55 goto drop; /* Muxed RTCP, ignore for now FIXME */
58 if (sys->srtp != NULL)
60 size_t len = block->i_buffer;
61 if (srtp_recv (sys->srtp, block->p_buffer, &len))
63 msg_Dbg (demux, "SRTP authentication/decryption failed");
66 block->i_buffer = len;
70 /* TODO: use SDP and get rid of this hack */
71 if (unlikely(sys->autodetect))
72 { /* Autodetect payload type, _before_ rtp_queue() */
73 rtp_autodetect (demux, sys->session, block);
74 sys->autodetect = false;
77 rtp_queue (demux, sys->session, block);
80 block_Release (block);
83 static int rtp_timeout (mtime_t deadline)
85 if (deadline == VLC_TS_INVALID)
86 return -1; /* infinite */
92 t = (deadline - t) / (CLOCK_FREQ / INT64_C(1000));
93 if (unlikely(t > INT_MAX))
99 * RTP/RTCP session thread for datagram sockets
101 void *rtp_dgram_thread (void *opaque)
103 demux_t *demux = opaque;
104 demux_sys_t *sys = demux->p_sys;
105 mtime_t deadline = VLC_TS_INVALID;
106 int rtp_fd = sys->fd;
108 struct pollfd ufd[1];
110 ufd[0].events = POLLIN;
114 int n = poll (ufd, 1, rtp_timeout (deadline));
118 int canc = vlc_savecancel ();
125 if (unlikely(ufd[0].revents & POLLHUP))
126 break; /* RTP socket dead (DCCP only) */
128 block_t *block = block_Alloc (0xffff); /* TODO: p_sys->mru */
129 if (unlikely(block == NULL))
130 break; /* we are totallly screwed */
132 ssize_t len = recv (rtp_fd, block->p_buffer, block->i_buffer, 0);
135 block->i_buffer = len;
136 rtp_process (demux, block);
140 msg_Warn (demux, "RTP network error: %s",
141 vlc_strerror_c(errno));
142 block_Release (block);
147 if (!rtp_dequeue (demux, sys->session, &deadline))
148 deadline = VLC_TS_INVALID;
149 vlc_restorecancel (canc);
155 * RTP/RTCP session thread for stream sockets (framed RTP)
157 void *rtp_stream_thread (void *opaque)
160 demux_t *demux = opaque;
161 demux_sys_t *sys = demux->p_sys;
166 /* There is no reordering on stream sockets, so no timeout. */
170 if (recv (fd, &frame_len, 2, MSG_WAITALL) != 2)
173 block_t *block = block_Alloc (ntohs (frame_len));
174 if (unlikely(block == NULL))
177 block_cleanup_push (block);
178 val = recv (fd, block->p_buffer, block->i_buffer, MSG_WAITALL);
181 if (val != (ssize_t)block->i_buffer)
183 block_Release (block);
187 int canc = vlc_savecancel ();
188 rtp_process (demux, block);
189 rtp_dequeue_force (demux, sys->session);
190 vlc_restorecancel (canc);