static void Close( vlc_object_t * );
#define SOUT_CFG_PREFIX "sout-rtp-"
+#define MAX_EMPTY_BLOCKS 200
vlc_module_begin();
set_shortname( _("RTP"));
block_t* );
static sout_access_out_t *GrabberCreate( sout_stream_t *p_sout );
+static void ThreadSend( vlc_object_t *p_this );
static void SDPHandleUrl( sout_stream_t *, char * );
struct sout_stream_id_t
{
+ VLC_COMMON_MEMBERS
+
sout_stream_t *p_stream;
/* rtp field */
uint32_t i_timestamp_start;
int fdc;
int *fdv;
rtsp_stream_id_t *rtsp_id;
+
+ block_fifo_t *p_fifo;
+ int64_t i_caching;
};
int i_port;
char *psz_sdp;
+ id = vlc_object_create( p_stream, sizeof( sout_stream_id_t ) );
+ if( id == NULL )
+ return NULL;
+
/* Choose the port */
i_port = 0;
if( p_fmt == NULL )
p_sys->i_port += 2;
}
- /* now create the rtp specific stuff */
- id = malloc( sizeof( sout_stream_id_t ) );
id->p_stream = p_stream;
id->i_timestamp_start = rand()&0xffffffff;
vlc_mutex_init( p_stream, &id->lock_sink );
id->fdc = 0;
id->fdv = NULL;
- id->rtsp_id = NULL;
+ id->rtsp_id = NULL;
+
+ id->i_caching =
+ (int64_t)1000 * var_GetInteger( p_stream, SOUT_CFG_PREFIX "caching");
+ id->p_fifo = block_FifoNew( p_stream );
+
+ if( vlc_thread_create( id, "RTP send thread", ThreadSend,
+ VLC_THREAD_PRIORITY_HIGHEST, VLC_FALSE ) )
+ {
+ vlc_mutex_destroy( &id->lock_sink );
+ vlc_object_destroy( id );
+ return NULL;
+ }
if( p_sys->psz_destination != NULL )
{
if( fd == -1 )
{
msg_Err( p_stream, "cannot create RTP socket" );
+ vlc_thread_join( id );
vlc_mutex_destroy( &id->lock_sink );
- free( id );
+ vlc_object_destroy( id );
return NULL;
}
rtp_add_sink( id, fd );
"codec:%4.4s)", (char*)&p_fmt->i_codec );
if( id->fdc > 0 )
rtp_del_sink( id, id->fdv[0] );
+ vlc_thread_join( id );
vlc_mutex_destroy( &id->lock_sink );
- free( id );
+ vlc_object_destroy( id );
return NULL;
}
if( p_sys->b_export_sap ) SapSetup( p_stream );
if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
+ vlc_object_attach( id, p_stream );
return id;
}
{
sout_stream_sys_t *p_sys = p_stream->p_sys;
+ vlc_object_kill( id );
+
vlc_mutex_lock( &p_sys->lock_es );
TAB_REMOVE( p_sys->i_es, p_sys->es, id );
vlc_mutex_unlock( &p_sys->lock_es );
if( id->fdc > 0 )
rtp_del_sink( id, id->fdv[0] ); /* sink for explicit dst= */
+ vlc_thread_join( id );
vlc_mutex_destroy( &id->lock_sink );
+ block_FifoRelease( id->p_fifo );
/* Update SDP (sap/file) */
if( p_sys->b_export_sap && !p_sys->p_mux ) SapSetup( p_stream );
if( p_sys->b_export_sdp_file ) FileSetup( p_stream );
- free( id );
+ vlc_object_detach( id );
+ vlc_object_destroy( id );
return VLC_SUCCESS;
}
}
/****************************************************************************
- * rtp_packetize_*:
+ * RTP send
****************************************************************************/
-static void rtp_packetize_common( sout_stream_id_t *id, block_t *out,
- int b_marker, int64_t i_pts )
+static void ThreadSend( vlc_object_t *p_this )
{
- uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000);
+ sout_stream_id_t *id = (sout_stream_id_t *)p_this;
+ unsigned i_caching = id->i_caching;
- out->p_buffer[0] = 0x80;
- out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
- out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
- out->p_buffer[3] = ( id->i_sequence )&0xff;
- out->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
- out->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
- out->p_buffer[6] = ( i_timestamp >> 8 )&0xff;
- out->p_buffer[7] = ( i_timestamp )&0xff;
+ while( !id->b_die )
+ {
+ block_t *out = block_FifoGet( id->p_fifo );
+ mtime_t i_date = out->i_dts + i_caching;
- memcpy( out->p_buffer + 8, id->ssrc, 4 );
+ mwait( i_date );
- out->i_buffer = 12;
- id->i_sequence++;
-}
+ vlc_mutex_lock( &id->lock_sink );
+ for( int i = 0; i < id->fdc; i++ )
+ send( id->fdv[i], out->p_buffer, out->i_buffer, 0 );
+ vlc_mutex_unlock( &id->lock_sink );
-static void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
-{
- int i;
- vlc_mutex_lock( &id->lock_sink );
- for( i = 0; i < id->fdc; i++ )
- {
- send( id->fdv[i], out->p_buffer, out->i_buffer, 0 );
+ block_Release( out );
}
- vlc_mutex_unlock( &id->lock_sink );
+}
- block_Release( out );
+static inline void rtp_packetize_send( sout_stream_id_t *id, block_t *out )
+{
+ block_FifoPut( id->p_fifo, out );
}
int rtp_add_sink( sout_stream_id_t *id, int fd )
net_Close( fd );
}
+/****************************************************************************
+ * rtp_packetize_*:
+ ****************************************************************************/
+static void rtp_packetize_common( sout_stream_id_t *id, block_t *out,
+ int b_marker, int64_t i_pts )
+{
+ uint32_t i_timestamp = i_pts * (int64_t)id->i_clock_rate / I64C(1000000);
+
+ out->p_buffer[0] = 0x80;
+ out->p_buffer[1] = (b_marker?0x80:0x00)|id->i_payload_type;
+ out->p_buffer[2] = ( id->i_sequence >> 8)&0xff;
+ out->p_buffer[3] = ( id->i_sequence )&0xff;
+ out->p_buffer[4] = ( i_timestamp >> 24 )&0xff;
+ out->p_buffer[5] = ( i_timestamp >> 16 )&0xff;
+ out->p_buffer[6] = ( i_timestamp >> 8 )&0xff;
+ out->p_buffer[7] = ( i_timestamp )&0xff;
+
+ memcpy( out->p_buffer + 8, id->ssrc, 4 );
+
+ out->i_buffer = 12;
+ id->i_sequence++;
+}
+
static int rtp_packetize_mpa( sout_stream_t *p_stream, sout_stream_id_t *id,
block_t *in )
{