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 General Public License
10 * as published by the Free Software Foundation; either version 2.0
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 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>
41 * Gets a datagram from the network.
42 * @param fd datagram file descriptor
43 * @return a block or NULL on fatal error (socket dead)
45 static block_t *rtp_dgram_recv (int fd)
47 block_t *block = block_Alloc (0xffff);
52 struct pollfd ufd = { .fd = fd, .events = POLLIN, };
54 block_cleanup_push (block);
56 len = recv (fd, block->p_buffer, block->i_buffer, 0);
59 if ((len <= 0) && (ufd.revents & POLLHUP))
60 { /* POLLHUP -> permanent (DCCP) socket error */
61 block_Release (block);
67 return block_Realloc (block, 0, len);
72 * Gets a framed RTP packet.
73 * @param fd stream file descriptor
74 * @return a block or NULL in case of fatal error
76 static block_t *rtp_stream_recv (int fd)
79 struct pollfd ufd = { .fd = fd, .events = POLLIN, };
80 uint8_t hdr[2]; /* frame header */
82 /* Receives the RTP frame header */
88 val = recv (fd, hdr + len, 2 - len, 0);
95 block_t *block = block_Alloc (GetWBE (hdr));
97 /* Receives the RTP packet */
98 for (ssize_t i = 0; i < len;)
102 block_cleanup_push (block);
104 val = recv (fd, block->p_buffer + i, block->i_buffer - i, 0);
109 block_Release (block);
119 static block_t *rtp_recv (demux_t *demux)
121 demux_sys_t *p_sys = demux->p_sys;
123 for (block_t *block;; block_Release (block))
125 block = p_sys->framed_rtp
126 ? rtp_stream_recv (p_sys->fd)
127 : rtp_dgram_recv (p_sys->fd);
130 msg_Err (demux, "RTP flow stopped");
131 break; /* fatal error */
134 if (block->i_buffer < 2)
138 const uint8_t ptype = rtp_ptype (block);
139 if (ptype >= 72 && ptype <= 76)
140 continue; /* Muxed RTCP, ignore for now */
144 size_t len = block->i_buffer;
147 canc = vlc_savecancel ();
148 err = srtp_recv (p_sys->srtp, block->p_buffer, &len);
149 vlc_restorecancel (canc);
152 msg_Dbg (demux, "SRTP authentication/decryption failed");
155 block->i_buffer = len;
157 return block; /* success! */
163 void *rtp_thread (void *data)
165 demux_t *demux = data;
166 demux_sys_t *p_sys = demux->p_sys;
170 block_t *block = rtp_recv (demux);
172 break; /* fatal error: abort */
174 vlc_mutex_lock (&p_sys->lock);
176 /* Autodetect payload type, _before_ rtp_queue() */
177 if (p_sys->autodetect)
179 if (rtp_autodetect (demux, p_sys->session, block))
181 block_Release (block);
184 p_sys->autodetect = false;
187 rtp_queue (demux, p_sys->session, block);
188 vlc_cond_signal (&p_sys->wait);
189 vlc_mutex_unlock (&p_sys->lock);
191 /* TODO: return 0 from Demux */
196 void rtp_process (demux_t *demux)
198 demux_sys_t *p_sys = demux->p_sys;
201 vlc_mutex_lock (&p_sys->lock);
202 if (!rtp_dequeue (demux, p_sys->session, &deadline))
203 deadline = mdate () + CLOCK_FREQ / 5;
204 vlc_cond_timedwait (&p_sys->wait, &p_sys->lock, deadline);
205 vlc_mutex_unlock (&p_sys->lock);