lib: media_player: fix aout callbacks having no effects
[vlc.git] / modules / access / rtp / input.c
blobd819fe5fff2bfa1fbcc73cfefff84336738bd6cb
1 /**
2 * @file input.c
3 * @brief RTP packet input
4 */
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 ****************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 # include <config.h>
25 #endif
27 #include <limits.h>
28 #include <errno.h>
29 #ifdef HAVE_POLL_H
30 # include <poll.h>
31 #endif
32 #ifdef HAVE_SYS_UIO_H
33 # include <sys/uio.h>
34 #endif
35 #ifdef _WIN32
36 # include <winsock2.h>
37 #endif
39 #include <vlc_common.h>
40 #include <vlc_demux.h>
41 #include <vlc_block.h>
42 #include <vlc_dtls.h>
44 #include "rtp.h"
45 #ifdef HAVE_SRTP
46 # include "srtp.h"
47 #endif
49 #define DEFAULT_MRU (1500u - (20 + 8))
51 /**
52 * Processes a packet received from the RTP socket.
54 static void rtp_process (demux_t *demux, block_t *block)
56 demux_sys_t *sys = demux->p_sys;
58 if (block->i_buffer < 2)
59 goto drop;
60 const uint8_t ptype = rtp_ptype (block);
61 if (ptype >= 72 && ptype <= 76)
62 goto drop; /* Muxed RTCP, ignore for now FIXME */
64 #ifdef HAVE_SRTP
65 if (sys->srtp != NULL)
67 size_t len = block->i_buffer;
68 if (srtp_recv (sys->srtp, block->p_buffer, &len))
70 msg_Dbg (demux, "SRTP authentication/decryption failed");
71 goto drop;
73 block->i_buffer = len;
75 #endif
77 /* TODO: use SDP and get rid of this hack */
78 if (unlikely(sys->autodetect))
79 { /* Autodetect payload type, _before_ rtp_queue() */
80 rtp_autodetect (demux, sys->session, block);
81 sys->autodetect = false;
84 rtp_queue (demux, sys->session, block);
85 return;
86 drop:
87 block_Release (block);
90 static int rtp_timeout (vlc_tick_t deadline)
92 if (deadline == VLC_TICK_INVALID)
93 return -1; /* infinite */
95 vlc_tick_t t = vlc_tick_now ();
96 if (t >= deadline)
97 return 0;
99 t = (deadline - t) / (CLOCK_FREQ / INT64_C(1000));
100 if (unlikely(t > INT_MAX))
101 return INT_MAX;
102 return t;
106 * RTP/RTCP session thread for datagram sockets
108 void *rtp_dgram_thread (void *opaque)
110 demux_t *demux = opaque;
111 demux_sys_t *sys = demux->p_sys;
112 vlc_tick_t deadline = VLC_TICK_INVALID;
113 struct vlc_dtls *rtp_sock = sys->rtp_sock;
115 for (;;)
117 struct pollfd ufd[1];
119 ufd[0].events = POLLIN;
120 ufd[0].fd = vlc_dtls_GetPollFD(rtp_sock, &ufd[0].events);
122 int n = poll (ufd, 1, rtp_timeout (deadline));
123 if (n == -1)
124 continue;
126 int canc = vlc_savecancel ();
127 if (n == 0)
128 goto dequeue;
130 if (ufd[0].revents)
132 block_t *block = block_Alloc(DEFAULT_MRU);
133 if (unlikely(block == NULL))
134 break; /* we are totallly screwed */
136 bool truncated;
137 ssize_t len = vlc_dtls_Recv(rtp_sock, block->p_buffer,
138 block->i_buffer, &truncated);
139 if (len >= 0) {
140 if (truncated) {
141 msg_Err(demux, "packet truncated (MRU was %zu)",
142 block->i_buffer);
143 block->i_flags |= BLOCK_FLAG_CORRUPTED;
145 else
146 block->i_buffer = len;
148 rtp_process (demux, block);
150 else
152 if (errno == EPIPE)
153 break; /* connection terminated */
154 msg_Warn (demux, "RTP network error: %s",
155 vlc_strerror_c(errno));
156 block_Release (block);
159 n--;
162 dequeue:
163 if (!rtp_dequeue (demux, sys->session, &deadline))
164 deadline = VLC_TICK_INVALID;
165 vlc_restorecancel (canc);
167 return NULL;