@ -60,6 +60,7 @@ typedef struct RTPContext {
char * sources ;
char * sources ;
char * block ;
char * block ;
char * fec_options_str ;
char * fec_options_str ;
int64_t rw_timeout ;
} RTPContext ;
} RTPContext ;
# define OFFSET(x) offsetof(RTPContext, x)
# define OFFSET(x) offsetof(RTPContext, x)
@ -75,6 +76,7 @@ static const AVOption options[] = {
{ " write_to_source " , " Send packets to the source address of the latest received packet " , OFFSET ( write_to_source ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , . flags = D | E } ,
{ " write_to_source " , " Send packets to the source address of the latest received packet " , OFFSET ( write_to_source ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , . flags = D | E } ,
{ " pkt_size " , " Maximum packet size " , OFFSET ( pkt_size ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , . flags = D | E } ,
{ " pkt_size " , " Maximum packet size " , OFFSET ( pkt_size ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , . flags = D | E } ,
{ " dscp " , " DSCP class " , OFFSET ( dscp ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , . flags = D | E } ,
{ " dscp " , " DSCP class " , OFFSET ( dscp ) , AV_OPT_TYPE_INT , { . i64 = - 1 } , - 1 , INT_MAX , . flags = D | E } ,
{ " timeout " , " set timeout (in microseconds) of socket I/O operations " , OFFSET ( rw_timeout ) , AV_OPT_TYPE_INT64 , { . i64 = - 1 } , - 1 , INT64_MAX , . flags = D | E } ,
{ " sources " , " Source list " , OFFSET ( sources ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = D | E } ,
{ " sources " , " Source list " , OFFSET ( sources ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = D | E } ,
{ " block " , " Block list " , OFFSET ( block ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = D | E } ,
{ " block " , " Block list " , OFFSET ( block ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = D | E } ,
{ " fec " , " FEC " , OFFSET ( fec_options_str ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = E } ,
{ " fec " , " FEC " , OFFSET ( fec_options_str ) , AV_OPT_TYPE_STRING , { . str = NULL } , . flags = E } ,
@ -265,6 +267,9 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
if ( av_find_info_tag ( buf , sizeof ( buf ) , " dscp " , p ) ) {
if ( av_find_info_tag ( buf , sizeof ( buf ) , " dscp " , p ) ) {
s - > dscp = strtol ( buf , NULL , 10 ) ;
s - > dscp = strtol ( buf , NULL , 10 ) ;
}
}
if ( av_find_info_tag ( buf , sizeof ( buf ) , " timeout " , p ) ) {
s - > rw_timeout = strtol ( buf , NULL , 10 ) ;
}
if ( av_find_info_tag ( buf , sizeof ( buf ) , " sources " , p ) ) {
if ( av_find_info_tag ( buf , sizeof ( buf ) , " sources " , p ) ) {
av_strlcpy ( include_sources , buf , sizeof ( include_sources ) ) ;
av_strlcpy ( include_sources , buf , sizeof ( include_sources ) ) ;
ff_ip_parse_sources ( h , buf , & s - > filters ) ;
ff_ip_parse_sources ( h , buf , & s - > filters ) ;
@ -280,6 +285,8 @@ static int rtp_open(URLContext *h, const char *uri, int flags)
block = s - > block ;
block = s - > block ;
}
}
}
}
if ( s - > rw_timeout > = 0 )
h - > rw_timeout = s - > rw_timeout ;
if ( s - > fec_options_str ) {
if ( s - > fec_options_str ) {
p = s - > fec_options_str ;
p = s - > fec_options_str ;
@ -375,9 +382,10 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
RTPContext * s = h - > priv_data ;
RTPContext * s = h - > priv_data ;
int len , n , i ;
int len , n , i ;
struct pollfd p [ 2 ] = { { s - > rtp_fd , POLLIN , 0 } , { s - > rtcp_fd , POLLIN , 0 } } ;
struct pollfd p [ 2 ] = { { s - > rtp_fd , POLLIN , 0 } , { s - > rtcp_fd , POLLIN , 0 } } ;
int poll_delay = h - > flags & AVIO_FLAG_NONBLOCK ? 0 : 100 ;
int poll_delay = h - > flags & AVIO_FLAG_NONBLOCK ? 0 : POLLING_TIME ;
struct sockaddr_storage * addrs [ 2 ] = { & s - > last_rtp_source , & s - > last_rtcp_source } ;
struct sockaddr_storage * addrs [ 2 ] = { & s - > last_rtp_source , & s - > last_rtcp_source } ;
socklen_t * addr_lens [ 2 ] = { & s - > last_rtp_source_len , & s - > last_rtcp_source_len } ;
socklen_t * addr_lens [ 2 ] = { & s - > last_rtp_source_len , & s - > last_rtcp_source_len } ;
int runs = h - > rw_timeout / 1000 / POLLING_TIME ;
for ( ; ; ) {
for ( ; ; ) {
if ( ff_check_interrupt ( & h - > interrupt_callback ) )
if ( ff_check_interrupt ( & h - > interrupt_callback ) )
@ -401,6 +409,8 @@ static int rtp_read(URLContext *h, uint8_t *buf, int size)
continue ;
continue ;
return len ;
return len ;
}
}
} else if ( n = = 0 & & h - > rw_timeout > 0 & & - - runs < = 0 ) {
return AVERROR ( ETIMEDOUT ) ;
} else if ( n < 0 ) {
} else if ( n < 0 ) {
if ( ff_neterrno ( ) = = AVERROR ( EINTR ) )
if ( ff_neterrno ( ) = = AVERROR ( EINTR ) )
continue ;
continue ;