* Preamble
*****************************************************************************/
-#include <vlc/vlc.h>
+#ifdef HAVE_CONFIG_H
+# include "config.h"
+#endif
+
+#include <vlc_common.h>
#include <vlc_block.h>
#include <vlc_network.h>
-
-
-#include <vlc_url.h>
#include <vlc_sout.h>
+#include <vlc_fs.h>
#include "rtp.h"
+#include <assert.h>
+
+#ifndef SOL_IP
+# define SOL_IP IPPROTO_IP
+#endif
+
/*
* NOTE on RTCP implementation:
* - there is a single sender (us), no conferencing here! => n = sender = 1,
struct rtcp_sender_t
{
size_t length; /* RTCP packet length */
- uint8_t payload[28 + 8 + (2 * 257)];
+ uint8_t payload[28 + 8 + (2 * 257) + 8];
int handle; /* RTCP socket handler */
uint32_t packets; /* RTP packets sent */
rtcp_sender_t *OpenRTCP (vlc_object_t *obj, int rtp_fd, int proto,
- vlc_bool_t mux)
+ bool mux)
{
rtcp_sender_t *rtcp;
uint8_t *ptr;
{
/* RTP/RTCP mux: duplicate the socket */
#ifndef WIN32
- fd = dup (rtp_fd);
+ fd = vlc_dup (rtp_fd);
+#elif defined(UNDER_CE)
+ #warning Muxed RTP/RTCP unimplemented!
+ fd = -1;
#else
WSAPROTOCOL_INFO info;
- WSADuplicateSocket (rtp_fd, GetProcessId (), &info);
- fd = WSASocket (info.iAddressFamily, info.iSockets, info.iProtocol,
+ WSADuplicateSocket (rtp_fd, GetCurrentProcessId (), &info);
+ fd = WSASocket (info.iAddressFamily, info.iSocketType, info.iProtocol,
&info, 0, 0);
#endif
}
dport++;
fd = net_OpenDgram (obj, src, sport, dst, dport, AF_UNSPEC, proto);
+ if (fd != -1)
+ {
+ /* Copy the multicast IPv4 TTL value (useless for IPv6) */
+ int ttl;
+ socklen_t len = sizeof (ttl);
+
+ if (!getsockopt (rtp_fd, SOL_IP, IP_MULTICAST_TTL, &ttl, &len))
+ setsockopt (fd, SOL_IP, IP_MULTICAST_TTL, &ttl, len);
+
+ /* Ignore all incoming RTCP-RR packets */
+ setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0 }, sizeof (int));
+ }
}
if (fd == -1)
while ((ptr - sdes) & 3) /* 32-bits padding */
*ptr++ = 0;
- SetWBE (lenptr, ptr - sdes);
+ SetWBE (lenptr, (ptr - sdes - 1) >> 2);
rtcp->length = ptr - rtcp->payload;
return rtcp;
return;
uint8_t *ptr = rtcp->payload;
+ uint64_t now64 = NTPtime64 ();
+ SetQWBE (ptr + 8, now64); /* Update the Sender Report timestamp */
+
/* Bye */
+ ptr += rtcp->length;
ptr[0] = (2 << 6) | 1; /* V = 2, P = 0, SC = 1 */
ptr[1] = 203; /* payload type: Bye */
SetWBE (ptr + 2, 1);
- /* SSRC is already there :) */
+ memcpy (ptr + 4, rtcp->payload + 4, 4); /* Copy SSRC from Sender Report */
+ rtcp->length += 8;
/* We are THE sender, so we are more important than anybody else, so
* we can afford not to check bandwidth constraints here. */
- send (rtcp->handle, rtcp->payload, 8, 0);
+ send (rtcp->handle, rtcp->payload, rtcp->length, 0);
net_Close (rtcp->handle);
+ free (rtcp);
}