From 215d5035cb2ec8a6f2a011d3ab00c4072c4ff631 Mon Sep 17 00:00:00 2001 From: Pierre Ynard Date: Sat, 12 Dec 2009 03:12:02 +0100 Subject: [PATCH] rtp sout: ensure seq value in rtsp is accurate Handle caching and fix race conditions --- modules/stream_out/rtp.c | 30 +++++++++++++++++++++++------- modules/stream_out/rtp.h | 4 ++-- modules/stream_out/rtsp.c | 7 +++++-- 3 files changed, 30 insertions(+), 11 deletions(-) diff --git a/modules/stream_out/rtp.c b/modules/stream_out/rtp.c index ff6388f661..0e65085cf2 100644 --- a/modules/stream_out/rtp.c +++ b/modules/stream_out/rtp.c @@ -52,6 +52,9 @@ # include # include #endif +#ifdef HAVE_ARPA_INET_H +# include +#endif #ifdef HAVE_LINUX_DCCP_H # include #endif @@ -312,6 +315,9 @@ struct sout_stream_id_t uint8_t i_payload_type; uint8_t ssrc[4]; + /* for rtsp */ + uint16_t i_seq_sent_next; + /* for sdp */ const char *psz_enc; char *psz_fmtp; @@ -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->ssrc, sizeof (id->ssrc)); + id->i_seq_sent_next = id->i_sequence; + id->psz_enc = NULL; id->psz_fmtp = NULL; 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 ) * packets in case of rtcp-mux) */ setsockopt (fd, SOL_SOCKET, SO_RCVBUF, &(int){ 0 }, 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 ) 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 ); block_Release( out ); @@ -1623,7 +1632,7 @@ static void *rtp_listen_thread( void *data ) if( fd == -1 ) continue; int canc = vlc_savecancel( ); - rtp_add_sink( id, fd, true ); + rtp_add_sink( id, fd, true, NULL ); vlc_restorecancel( canc ); } @@ -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 }; 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 ) vlc_mutex_lock( &id->lock_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 ); return VLC_SUCCESS; } @@ -1666,11 +1677,16 @@ void rtp_del_sink( sout_stream_id_t *id, int 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. - * Accounting for caching would not be totally trivial. */ - return id->i_sequence; + /* This will return values for the next packet. */ + uint16_t seq; + + 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 diff --git a/modules/stream_out/rtp.h b/modules/stream_out/rtp.h index aec9dde925..5372146120 100644 --- a/modules/stream_out/rtp.h +++ b/modules/stream_out/rtp.h @@ -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 ); -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 ); -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 ); /* RTP packetization */ diff --git a/modules/stream_out/rtsp.c b/modules/stream_out/rtsp.c index 61d81fac65..a8e302788d 100644 --- a/modules/stream_out/rtsp.c +++ b/modules/stream_out/rtsp.c @@ -646,16 +646,19 @@ static int RtspHandler( rtsp_stream_t *rtsp, rtsp_stream_id_t *id, rtsp_strack_t *tr = ses->trackv + i; if( ( id == NULL ) || ( tr->id == id->sout_id ) ) { + uint16_t seq; if( !tr->playing ) { 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, "url=%s/trackID=%u;seq=%u, ", control, rtp_get_num( tr->id ), - rtp_get_seq( tr->id ) ); + seq ); } } if( infolen > 0 ) -- 2.39.2