@ -266,7 +266,8 @@ struct ast_rtp {
unsigned int lastitexttimestamp ;
unsigned int lastotexttimestamp ;
unsigned int lasteventseqn ;
int lastrxseqno ; /*!< Last received sequence number */
int lastrxseqno ; /*!< Last received sequence number, from the network */
int expectedseqno ; /*!< Next expected sequence number, from the core */
unsigned short seedrxseqno ; /*!< What sequence number did they start with?*/
unsigned int seedrxts ; /*!< What RTP timestamp did they start with? */
unsigned int rxcount ; /*!< How many packets have we received? */
@ -3245,6 +3246,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
rtp - > ssrc = ast_random ( ) ;
ast_uuid_generate_str ( rtp - > cname , sizeof ( rtp - > cname ) ) ;
rtp - > seqno = ast_random ( ) & 0x7fff ;
rtp - > expectedseqno = - 1 ;
rtp - > sched = sched ;
ast_sockaddr_copy ( & rtp - > bind_address , addr ) ;
@ -3274,7 +3276,7 @@ static int ast_rtp_new(struct ast_rtp_instance *instance,
* \ return 0 if element does not match .
* \ return Non - zero if element matches .
*/
# define SSRC_MAPPING_ELEM_CMP(elem, value) ( (elem).ssrc == (value) )
# define SSRC_MAPPING_ELEM_CMP(elem, value) ( elem.instance == value )
/*! \pre instance is locked */
static int ast_rtp_destroy ( struct ast_rtp_instance * instance )
@ -3289,7 +3291,7 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance)
ao2_lock ( rtp - > bundled ) ;
bundled_rtp = ast_rtp_instance_get_data ( rtp - > bundled ) ;
AST_VECTOR_REMOVE_CMP_UNORDERED ( & bundled_rtp - > ssrc_mapping , rtp- > themssrc , SSRC_MAPPING_ELEM_CMP , AST_VECTOR_ELEM_CLEANUP_NOOP ) ;
AST_VECTOR_REMOVE_CMP_UNORDERED ( & bundled_rtp - > ssrc_mapping , instance , SSRC_MAPPING_ELEM_CMP , AST_VECTOR_ELEM_CLEANUP_NOOP ) ;
ao2_unlock ( rtp - > bundled ) ;
ao2_lock ( instance ) ;
@ -3897,6 +3899,7 @@ static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *fr
unsigned int ms = calc_txstamp ( rtp , & frame - > delivery ) ;
struct ast_sockaddr remote_address = { { 0 , } } ;
int rate = rtp_get_rate ( frame - > subclass . format ) / 1000 ;
unsigned int seqno ;
if ( ast_format_cmp ( frame - > subclass . format , ast_format_g722 ) = = AST_FORMAT_CMP_EQUAL ) {
frame - > samples / = 2 ;
@ -3963,6 +3966,40 @@ static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *fr
rtp - > lastdigitts = rtp - > lastts ;
}
/* Assume that the sequence number we expect to use is what will be used until proven otherwise */
seqno = rtp - > seqno ;
/* If the frame contains sequence number information use it to influence our sequence number */
if ( ast_test_flag ( frame , AST_FRFLAG_HAS_SEQUENCE_NUMBER ) ) {
if ( rtp - > expectedseqno ! = - 1 ) {
/* Determine where the frame from the core is in relation to where we expected */
int difference = frame - > seqno - rtp - > expectedseqno ;
/* If there is a substantial difference then we've either got packets really out
* of order , or the source is RTP and it has cycled . If this happens we resync
* the sequence number adjustments to this frame . If we also have packet loss
* things won ' t be reflected correctly but it will sort itself out after a bit .
*/
if ( abs ( difference ) > 100 ) {
difference = 0 ;
}
/* Adjust the sequence number being used for this packet accordingly */
seqno + = difference ;
if ( difference > = 0 ) {
/* This frame is on time or in the future */
rtp - > expectedseqno = frame - > seqno + 1 ;
rtp - > seqno + = difference ;
}
} else {
/* This is the first frame with sequence number we've seen, so start keeping track */
rtp - > expectedseqno = frame - > seqno + 1 ;
}
} else {
rtp - > expectedseqno = - 1 ;
}
if ( ast_test_flag ( frame , AST_FRFLAG_HAS_TIMING_INFO ) ) {
rtp - > lastts = frame - > ts * rate ;
}
@ -3974,7 +4011,7 @@ static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *fr
int hdrlen = 12 , res , ice ;
unsigned char * rtpheader = ( unsigned char * ) ( frame - > data . ptr - hdrlen ) ;
put_unaligned_uint32 ( rtpheader , htonl ( ( 2 < < 30 ) | ( codec < < 16 ) | ( rtp- > seqno) | ( mark < < 23 ) ) ) ;
put_unaligned_uint32 ( rtpheader , htonl ( ( 2 < < 30 ) | ( codec < < 16 ) | ( seqno) | ( mark < < 23 ) ) ) ;
put_unaligned_uint32 ( rtpheader + 4 , htonl ( rtp - > lastts ) ) ;
put_unaligned_uint32 ( rtpheader + 8 , htonl ( rtp - > ssrc ) ) ;
@ -4011,7 +4048,13 @@ static int rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *fr
}
}
rtp - > seqno + + ;
/* If the sequence number that has been used doesn't match what we expected then this is an out of
* order late packet , so we don ' t need to increment as we haven ' t yet gotten the expected frame from
* the core .
*/
if ( seqno = = rtp - > seqno ) {
rtp - > seqno + + ;
}
return 0 ;
}
@ -5474,6 +5517,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
rtp - > f . datalen = res - hdrlen ;
rtp - > f . data . ptr = read_area + hdrlen ;
rtp - > f . offset = hdrlen + AST_FRIENDLY_OFFSET ;
ast_set_flag ( & rtp - > f , AST_FRFLAG_HAS_SEQUENCE_NUMBER ) ;
rtp - > f . seqno = seqno ;
rtp - > f . stream_num = rtp - > stream_num ;
@ -6082,7 +6126,7 @@ static void ast_rtp_set_stream_num(struct ast_rtp_instance *instance, int stream
static int ast_rtp_bundle ( struct ast_rtp_instance * child , struct ast_rtp_instance * parent )
{
struct ast_rtp * child_rtp = ast_rtp_instance_get_data ( child ) ;
struct ast_rtp * parent_rtp = ast_rtp_instance_get_data ( parent ) ;
struct ast_rtp * parent_rtp ;
struct rtp_ssrc_mapping mapping ;
struct ast_sockaddr them = { { 0 , } } ;
@ -6099,7 +6143,7 @@ static int ast_rtp_bundle(struct ast_rtp_instance *child, struct ast_rtp_instanc
/* The child lock can't be held while accessing the parent */
ao2_lock ( child_rtp - > bundled ) ;
bundled_rtp = ast_rtp_instance_get_data ( child_rtp - > bundled ) ;
AST_VECTOR_REMOVE_CMP_UNORDERED ( & bundled_rtp - > ssrc_mapping , child _rtp- > themssrc , SSRC_MAPPING_ELEM_CMP , AST_VECTOR_ELEM_CLEANUP_NOOP ) ;
AST_VECTOR_REMOVE_CMP_UNORDERED ( & bundled_rtp - > ssrc_mapping , child , SSRC_MAPPING_ELEM_CMP , AST_VECTOR_ELEM_CLEANUP_NOOP ) ;
ao2_unlock ( child_rtp - > bundled ) ;
ao2_lock ( child ) ;
@ -6113,6 +6157,8 @@ static int ast_rtp_bundle(struct ast_rtp_instance *child, struct ast_rtp_instanc
return 0 ;
}
parent_rtp = ast_rtp_instance_get_data ( parent ) ;
/* We no longer need any transport related resources as we will use our parent RTP instance instead */
rtp_deallocate_transport ( child , child_rtp ) ;