Merge "res_rtp_asterisk.c: Fix bundled SSRC handling."

pull/9/head
Joshua Colp 8 years ago committed by Gerrit Code Review
commit 63a3d17f0b

@ -257,6 +257,8 @@ struct ice_wrap {
struct rtp_ssrc_mapping {
/*! \brief The received SSRC */
unsigned int ssrc;
/*! True if the SSRC is available. Otherwise, this is a placeholder mapping until the SSRC is set. */
unsigned int ssrc_valid;
/*! \brief The RTP instance this SSRC belongs to*/
struct ast_rtp_instance *instance;
};
@ -3344,7 +3346,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.instance == 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)
@ -4788,18 +4790,26 @@ static struct ast_rtp_instance *rtp_find_instance_by_ssrc(struct ast_rtp_instanc
struct ast_rtp *rtp, unsigned int ssrc)
{
int index;
struct ast_rtp_instance *found = instance;
if (!AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
/* This instance is not bundled */
return instance;
}
/* Find the bundled child instance */
for (index = 0; index < AST_VECTOR_SIZE(&rtp->ssrc_mapping); ++index) {
struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&rtp->ssrc_mapping, index);
if (mapping->ssrc == ssrc) {
found = mapping->instance;
break;
if (mapping->ssrc_valid && mapping->ssrc == ssrc) {
return mapping->instance;
}
}
return found;
/* Does the SSRC match the bundled parent? */
if (rtp->themssrc_valid && rtp->themssrc == ssrc) {
return instance;
}
return NULL;
}
static const char *rtcp_payload_type2str(unsigned int pt)
@ -5040,7 +5050,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c
/* Determine the appropriate instance for this */
if (ssrc_valid) {
child = rtp_find_instance_by_ssrc(transport, transport_rtp, ssrc);
if (child != transport) {
if (child && child != transport) {
/*
* It is safe to hold the child lock while holding the parent lock.
* We guarantee that the locking order is always parent->child or
@ -5551,6 +5561,10 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
/* Determine the appropriate instance for this */
child = rtp_find_instance_by_ssrc(instance, rtp, ssrc);
if (!child) {
/* Neither the bundled parent nor any child has this SSRC */
return &ast_null_frame;
}
if (child != instance) {
/* It is safe to hold the child lock while holding the parent lock, we guarantee that the locking order
* is always parent->child or that the child lock is not held when acquiring the parent lock.
@ -5726,39 +5740,42 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
timestamp = ntohl(rtpheader[1]);
AST_LIST_HEAD_INIT_NOLOCK(&frames);
/* Force a marker bit and change SSRC if the SSRC changes */
if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
struct ast_frame *f, srcupdate = {
AST_FRAME_CONTROL,
.subclass.integer = AST_CONTROL_SRCCHANGE,
};
if (!mark) {
if (rtpdebug) {
ast_debug(1, "Forcing Marker bit, because SSRC has changed\n");
/* Only non-bundled instances can change/learn the remote's SSRC implicitly. */
if (!child && !AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
/* Force a marker bit and change SSRC if the SSRC changes */
if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
struct ast_frame *f, srcupdate = {
AST_FRAME_CONTROL,
.subclass.integer = AST_CONTROL_SRCCHANGE,
};
if (!mark) {
if (rtpdebug) {
ast_debug(1, "Forcing Marker bit, because SSRC has changed\n");
}
mark = 1;
}
mark = 1;
}
f = ast_frisolate(&srcupdate);
AST_LIST_INSERT_TAIL(&frames, f, frame_list);
f = ast_frisolate(&srcupdate);
AST_LIST_INSERT_TAIL(&frames, f, frame_list);
rtp->seedrxseqno = 0;
rtp->rxcount = 0;
rtp->rxoctetcount = 0;
rtp->cycles = 0;
rtp->lastrxseqno = 0;
rtp->last_seqno = 0;
rtp->last_end_timestamp = 0;
if (rtp->rtcp) {
rtp->rtcp->expected_prior = 0;
rtp->rtcp->received_prior = 0;
rtp->seedrxseqno = 0;
rtp->rxcount = 0;
rtp->rxoctetcount = 0;
rtp->cycles = 0;
rtp->lastrxseqno = 0;
rtp->last_seqno = 0;
rtp->last_end_timestamp = 0;
if (rtp->rtcp) {
rtp->rtcp->expected_prior = 0;
rtp->rtcp->received_prior = 0;
}
}
rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
rtp->themssrc_valid = 1;
}
/* Bundled children cannot change/learn their SSRC implicitly. */
ast_assert(!child || (rtp->themssrc_valid && rtp->themssrc == ssrc));
rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
rtp->themssrc_valid = 1;
/* Remove any padding bytes that may be present */
if (padding) {
@ -6520,13 +6537,14 @@ static void ast_rtp_set_remote_ssrc(struct ast_rtp_instance *instance, unsigned
return;
}
rtp->themssrc = ssrc;
rtp->themssrc_valid = 1;
/* If this is bundled we need to update the SSRC mapping */
if (rtp->bundled) {
struct ast_rtp *bundled_rtp;
int index;
ast_assert(rtp->themssrc_valid);
ao2_unlock(instance);
/* The child lock can't be held while accessing the parent */
@ -6536,8 +6554,9 @@ static void ast_rtp_set_remote_ssrc(struct ast_rtp_instance *instance, unsigned
for (index = 0; index < AST_VECTOR_SIZE(&bundled_rtp->ssrc_mapping); ++index) {
struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&bundled_rtp->ssrc_mapping, index);
if (mapping->ssrc == rtp->themssrc) {
if (mapping->instance == instance) {
mapping->ssrc = ssrc;
mapping->ssrc_valid = 1;
break;
}
}
@ -6546,9 +6565,6 @@ static void ast_rtp_set_remote_ssrc(struct ast_rtp_instance *instance, unsigned
ao2_lock(instance);
}
rtp->themssrc = ssrc;
rtp->themssrc_valid = 1;
}
static void ast_rtp_set_stream_num(struct ast_rtp_instance *instance, int stream_num)
@ -6601,8 +6617,8 @@ static int ast_rtp_bundle(struct ast_rtp_instance *child, struct ast_rtp_instanc
/* Children maintain a reference to the parent to guarantee that the transport doesn't go away on them */
child_rtp->bundled = ao2_bump(parent);
ast_assert(child_rtp->themssrc_valid);
mapping.ssrc = child_rtp->themssrc;
mapping.ssrc_valid = child_rtp->themssrc_valid;
mapping.instance = child;
ao2_unlock(child);

Loading…
Cancel
Save