};
-rtcp_sender_t *OpenRTCP (vlc_object_t *obj, int rtp_fd, int proto)
+rtcp_sender_t *OpenRTCP (vlc_object_t *obj, int rtp_fd, int proto,
+ vlc_bool_t mux)
{
rtcp_sender_t *rtcp;
uint8_t *ptr;
- char src[NI_MAXNUMERICHOST], dst[NI_MAXNUMERICHOST];
- int sport, dport;
int fd;
+ char src[NI_MAXNUMERICHOST];
+ int sport;
- if (net_GetSockAddress (rtp_fd, src, &sport)
- || net_GetPeerAddress (rtp_fd, dst, &dport))
+ if (net_GetSockAddress (rtp_fd, src, &sport))
return NULL;
- sport++;
- dport++;
+ if (mux)
+ {
+ /* RTP/RTCP mux: duplicate the socket */
+#ifndef WIN32
+ fd = dup (rtp_fd);
+#else
+ WSAPROTOCOL_INFO info;
+ WSADuplicateSocket (rtp_fd, GetProcessId (), &info);
+ fd = WSASocket (info.iAddressFamily, info.iSockets, info.iProtocol,
+ &info, 0, 0);
+#endif
+ }
+ else
+ {
+ /* RTCP on a separate port */
+ char dst[NI_MAXNUMERICHOST];
+ int dport;
+
+ if (net_GetPeerAddress (rtp_fd, dst, &dport))
+ return NULL;
+
+ sport++;
+ dport++;
+
+ fd = net_OpenDgram (obj, src, sport, dst, dport, AF_UNSPEC, proto);
+ }
- fd = net_OpenDgram (obj, src, sport, dst, dport, AF_UNSPEC, proto);
if (fd == -1)
return NULL;
int rtp_add_sink( sout_stream_id_t *id, int fd )
{
rtp_sink_t sink = { fd, NULL };
- sink.rtcp = OpenRTCP( VLC_OBJECT( id->p_stream ), fd, IPPROTO_UDP );
+ sink.rtcp = OpenRTCP( VLC_OBJECT( id->p_stream ), fd, IPPROTO_UDP, 0 );
if( sink.rtcp == NULL )
msg_Err( id, "RTCP failed!" );
/* RTCP */
typedef struct rtcp_sender_t rtcp_sender_t;
-rtcp_sender_t *OpenRTCP (vlc_object_t *obj, int rtp_fd, int proto);
+rtcp_sender_t *OpenRTCP (vlc_object_t *obj, int rtp_fd, int proto,
+ vlc_bool_t mux);
void CloseRTCP (rtcp_sender_t *rtcp);
void SendRTCP (rtcp_sender_t *restrict rtcp, const block_t *rtp);