Commit 215d5035 authored by Pierre Ynard's avatar Pierre Ynard

rtp sout: ensure seq value in rtsp is accurate

Handle caching and fix race conditions
parent b6cec887
...@@ -52,6 +52,9 @@ ...@@ -52,6 +52,9 @@
# include <fcntl.h> # include <fcntl.h>
# include <sys/stat.h> # include <sys/stat.h>
#endif #endif
#ifdef HAVE_ARPA_INET_H
# include <arpa/inet.h>
#endif
#ifdef HAVE_LINUX_DCCP_H #ifdef HAVE_LINUX_DCCP_H
# include <linux/dccp.h> # include <linux/dccp.h>
#endif #endif
...@@ -312,6 +315,9 @@ struct sout_stream_id_t ...@@ -312,6 +315,9 @@ struct sout_stream_id_t
uint8_t i_payload_type; uint8_t i_payload_type;
uint8_t ssrc[4]; uint8_t ssrc[4];
/* for rtsp */
uint16_t i_seq_sent_next;
/* for sdp */ /* for sdp */
const char *psz_enc; const char *psz_enc;
char *psz_fmtp; char *psz_fmtp;
...@@ -925,6 +931,8 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ) ...@@ -925,6 +931,8 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
vlc_rand_bytes (&id->i_sequence, sizeof (id->i_sequence)); vlc_rand_bytes (&id->i_sequence, sizeof (id->i_sequence));
vlc_rand_bytes (id->ssrc, sizeof (id->ssrc)); vlc_rand_bytes (id->ssrc, sizeof (id->ssrc));
id->i_seq_sent_next = id->i_sequence;
id->psz_enc = NULL; id->psz_enc = NULL;
id->psz_fmtp = NULL; id->psz_fmtp = NULL;
id->i_clock_rate = 90000; /* most common case for video */ id->i_clock_rate = 90000; /* most common case for video */
...@@ -1037,7 +1045,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt ) ...@@ -1037,7 +1045,7 @@ static sout_stream_id_t *Add( sout_stream_t *p_stream, es_format_t *p_fmt )
* packets in case of rtcp-mux) */ * packets in case of rtcp-mux) */
setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0 }, setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0 },
sizeof (int)); sizeof (int));
rtp_add_sink( id, fd, p_sys->rtcp_mux ); rtp_add_sink( id, fd, p_sys->rtcp_mux, NULL );
} }
} }
...@@ -1596,6 +1604,7 @@ static void* ThreadSend( vlc_object_t *p_this ) ...@@ -1596,6 +1604,7 @@ static void* ThreadSend( vlc_object_t *p_this )
deadv[deadc++] = id->sinkv[i].rtp_fd; deadv[deadc++] = id->sinkv[i].rtp_fd;
} }
id->i_seq_sent_next = ntohs(((uint16_t *) out->p_buffer)[1]) + 1;
vlc_mutex_unlock( &id->lock_sink ); vlc_mutex_unlock( &id->lock_sink );
block_Release( out ); block_Release( out );
...@@ -1623,7 +1632,7 @@ static void *rtp_listen_thread( void *data ) ...@@ -1623,7 +1632,7 @@ static void *rtp_listen_thread( void *data )
if( fd == -1 ) if( fd == -1 )
continue; continue;
int canc = vlc_savecancel( ); int canc = vlc_savecancel( );
rtp_add_sink( id, fd, true ); rtp_add_sink( id, fd, true, NULL );
vlc_restorecancel( canc ); vlc_restorecancel( canc );
} }
...@@ -1631,7 +1640,7 @@ static void *rtp_listen_thread( void *data ) ...@@ -1631,7 +1640,7 @@ static void *rtp_listen_thread( void *data )
} }
int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux ) int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux, uint16_t *seq )
{ {
rtp_sink_t sink = { fd, NULL }; 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,
...@@ -1641,6 +1650,8 @@ int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux ) ...@@ -1641,6 +1650,8 @@ int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux )
vlc_mutex_lock( &id->lock_sink ); vlc_mutex_lock( &id->lock_sink );
INSERT_ELEM( id->sinkv, id->sinkc, id->sinkc, sink ); INSERT_ELEM( id->sinkv, id->sinkc, id->sinkc, sink );
if( seq != NULL )
*seq = id->i_seq_sent_next;
vlc_mutex_unlock( &id->lock_sink ); vlc_mutex_unlock( &id->lock_sink );
return VLC_SUCCESS; return VLC_SUCCESS;
} }
...@@ -1666,11 +1677,16 @@ void rtp_del_sink( sout_stream_id_t *id, int fd ) ...@@ -1666,11 +1677,16 @@ void rtp_del_sink( sout_stream_id_t *id, int fd )
net_Close( sink.rtp_fd ); net_Close( sink.rtp_fd );
} }
uint16_t rtp_get_seq( const sout_stream_id_t *id ) uint16_t rtp_get_seq( sout_stream_id_t *id )
{ {
/* This will return values for the next packet. /* This will return values for the next packet. */
* Accounting for caching would not be totally trivial. */ uint16_t seq;
return id->i_sequence;
vlc_mutex_lock( &id->lock_sink );
seq = id->i_seq_sent_next;
vlc_mutex_unlock( &id->lock_sink );
return seq;
} }
/* FIXME: this is pretty bad - if we remove and then insert an ES /* FIXME: this is pretty bad - if we remove and then insert an ES
......
...@@ -36,9 +36,9 @@ void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t * ); ...@@ -36,9 +36,9 @@ void RtspDelId( rtsp_stream_t *rtsp, rtsp_stream_id_t * );
char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url ); char *SDPGenerate( const sout_stream_t *p_stream, const char *rtsp_url );
int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux ); int rtp_add_sink( sout_stream_id_t *id, int fd, bool rtcp_mux, uint16_t *seq );
void rtp_del_sink( sout_stream_id_t *id, int fd ); void rtp_del_sink( sout_stream_id_t *id, int fd );
uint16_t rtp_get_seq( const sout_stream_id_t *id ); uint16_t rtp_get_seq( sout_stream_id_t *id );
unsigned rtp_get_num( const sout_stream_id_t *id ); unsigned rtp_get_num( const sout_stream_id_t *id );
/* RTP packetization */ /* RTP packetization */
......
...@@ -646,16 +646,19 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id, ...@@ -646,16 +646,19 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id,
rtsp_strack_t *tr = ses->trackv + i; rtsp_strack_t *tr = ses->trackv + i;
if( ( id == NULL ) || ( tr->id == id->sout_id ) ) if( ( id == NULL ) || ( tr->id == id->sout_id ) )
{ {
uint16_t seq;
if( !tr->playing ) if( !tr->playing )
{ {
tr->playing = true; tr->playing = true;
rtp_add_sink( tr->id, tr->fd, false ); rtp_add_sink( tr->id, tr->fd, false, &seq );
} }
else
seq = rtp_get_seq( tr->id );
infolen += sprintf( info + infolen, infolen += sprintf( info + infolen,
"url=%s/trackID=%u;seq=%u, ", "url=%s/trackID=%u;seq=%u, ",
control, control,
rtp_get_num( tr->id ), rtp_get_num( tr->id ),
rtp_get_seq( tr->id ) ); seq );
} }
} }
if( infolen > 0 ) if( infolen > 0 )
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment