Merge "res_rtp_asterisk.c: Send RTCP as compound packets." into 16
This commit is contained in:
commit
51e315765b
|
@ -215,7 +215,6 @@ static ast_rwlock_t ice_blacklist_lock = AST_RWLOCK_INIT_VALUE;
|
|||
static struct ast_ha *stun_blacklist = NULL;
|
||||
static ast_rwlock_t stun_blacklist_lock = AST_RWLOCK_INIT_VALUE;
|
||||
|
||||
|
||||
/*! \brief Pool factory used by pjlib to allocate memory. */
|
||||
static pj_caching_pool cachingpool;
|
||||
|
||||
|
@ -4500,6 +4499,41 @@ static int ast_rtcp_generate_sdes(struct ast_rtp_instance *instance, unsigned ch
|
|||
return len;
|
||||
}
|
||||
|
||||
/* Lock instance before calling this if it isn't already
|
||||
*
|
||||
* If successful, the overall packet length is returned
|
||||
* If not, then 0 is returned
|
||||
*/
|
||||
static int ast_rtcp_generate_compound_prefix(struct ast_rtp_instance *instance, unsigned char *rtcpheader,
|
||||
struct ast_rtp_rtcp_report *report, int *sr)
|
||||
{
|
||||
int packet_len = 0;
|
||||
int res;
|
||||
|
||||
/* Every RTCP packet needs to be sent out with a SR/RR and SDES prefixing it.
|
||||
* At the end of this function, rtcpheader should contain both of those packets,
|
||||
* and will return the length of the overall packet. This can be used to determine
|
||||
* where further packets can be inserted in the compound packet.
|
||||
*/
|
||||
res = ast_rtcp_generate_report(instance, rtcpheader, report, sr);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ast_debug(1, "Failed to generate %s report!\n", sr ? "SR" : "RR");
|
||||
return 0;
|
||||
}
|
||||
|
||||
packet_len += res;
|
||||
|
||||
res = ast_rtcp_generate_sdes(instance, rtcpheader + packet_len, report);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ast_debug(1, "Failed to generate SDES!\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return packet_len + res;
|
||||
}
|
||||
|
||||
static int ast_rtcp_generate_nack(struct ast_rtp_instance *instance, unsigned char *rtcpheader)
|
||||
{
|
||||
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
|
||||
|
@ -4590,19 +4624,9 @@ static int ast_rtcp_write(const void *data)
|
|||
ao2_lock(instance);
|
||||
rtcpheader = bdata;
|
||||
|
||||
res = ast_rtcp_generate_report(instance, rtcpheader, rtcp_report, &sr);
|
||||
res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ast_debug(1, "Failed to add %s report to RTCP packet!\n", sr ? "SR" : "RR");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
packet_len += res;
|
||||
|
||||
res = ast_rtcp_generate_sdes(instance, rtcpheader + packet_len, rtcp_report);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ast_debug(1, "Failed to add SDES to RTCP packet!\n");
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
|
@ -4920,11 +4944,16 @@ static struct ast_frame *red_t140_to_red(struct rtp_red *red)
|
|||
|
||||
static void rtp_write_rtcp_fir(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *remote_address)
|
||||
{
|
||||
unsigned int *rtcpheader;
|
||||
char bdata[1024];
|
||||
int len = 20;
|
||||
unsigned char *rtcpheader;
|
||||
unsigned char bdata[1024];
|
||||
int packet_len = 0;
|
||||
int fir_len = 20;
|
||||
int ice;
|
||||
int res;
|
||||
int sr;
|
||||
RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report,
|
||||
ast_rtp_rtcp_report_alloc(rtp->themssrc_valid ? 1 : 0),
|
||||
ao2_cleanup);
|
||||
|
||||
if (!rtp || !rtp->rtcp) {
|
||||
return;
|
||||
|
@ -4948,26 +4977,46 @@ static void rtp_write_rtcp_fir(struct ast_rtp_instance *instance, struct ast_rtp
|
|||
rtp->rtcp->firseq = 0;
|
||||
}
|
||||
|
||||
rtcpheader = (unsigned int *)bdata;
|
||||
rtcpheader[0] = htonl((2 << 30) | (4 << 24) | (RTCP_PT_PSFB << 16) | ((len/4)-1));
|
||||
rtcpheader[1] = htonl(rtp->ssrc);
|
||||
rtcpheader[2] = htonl(rtp->themssrc);
|
||||
rtcpheader[3] = htonl(rtp->themssrc); /* FCI: SSRC */
|
||||
rtcpheader[4] = htonl(rtp->rtcp->firseq << 24); /* FCI: Sequence number */
|
||||
res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice);
|
||||
rtcpheader = bdata;
|
||||
|
||||
ao2_lock(instance);
|
||||
res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ao2_unlock(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_len += res;
|
||||
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 0, htonl((2 << 30) | (4 << 24) | (RTCP_PT_PSFB << 16) | ((fir_len/4)-1)));
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 4, htonl(rtp->ssrc));
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 8, htonl(rtp->themssrc));
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 12, htonl(rtp->themssrc)); /* FCI: SSRC */
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 16, htonl(rtp->rtcp->firseq << 24)); /* FCI: Sequence number */
|
||||
res = rtcp_sendto(instance, (unsigned int *)rtcpheader, packet_len + fir_len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_ERROR, "RTCP FIR transmission error: %s\n", strerror(errno));
|
||||
} else {
|
||||
ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, rtp->bundled ? *remote_address : rtp->rtcp->them, ice, sr);
|
||||
}
|
||||
|
||||
ao2_unlock(instance);
|
||||
}
|
||||
|
||||
static void rtp_write_rtcp_psfb(struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_frame *frame, struct ast_sockaddr *remote_address)
|
||||
{
|
||||
struct ast_rtp_rtcp_feedback *feedback = frame->data.ptr;
|
||||
unsigned int *rtcpheader;
|
||||
char bdata[1024];
|
||||
int len = 24;
|
||||
unsigned char *rtcpheader;
|
||||
unsigned char bdata[1024];
|
||||
int remb_len = 24;
|
||||
int ice;
|
||||
int res;
|
||||
int sr = 0;
|
||||
int packet_len = 0;
|
||||
RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report,
|
||||
ast_rtp_rtcp_report_alloc(rtp->themssrc_valid ? 1 : 0),
|
||||
ao2_cleanup);
|
||||
|
||||
if (feedback->fmt != AST_RTP_RTCP_FMT_REMB) {
|
||||
ast_debug(1, "Provided an RTCP feedback frame of format %d to write on RTP instance '%p' but only REMB is supported\n",
|
||||
|
@ -4993,17 +5042,32 @@ static void rtp_write_rtcp_psfb(struct ast_rtp_instance *instance, struct ast_rt
|
|||
return;
|
||||
}
|
||||
|
||||
rtcpheader = (unsigned int *)bdata;
|
||||
rtcpheader[0] = htonl((2 << 30) | (AST_RTP_RTCP_FMT_REMB << 24) | (RTCP_PT_PSFB << 16) | ((len/4)-1));
|
||||
rtcpheader[1] = htonl(rtp->ssrc);
|
||||
rtcpheader[2] = htonl(0); /* Per the draft this should always be 0 */
|
||||
rtcpheader[3] = htonl(('R' << 24) | ('E' << 16) | ('M' << 8) | ('B')); /* Unique identifier 'R' 'E' 'M' 'B' */
|
||||
rtcpheader[4] = htonl((1 << 24) | (feedback->remb.br_exp << 18) | (feedback->remb.br_mantissa)); /* Number of SSRCs / BR Exp / BR Mantissa */
|
||||
rtcpheader[5] = htonl(rtp->ssrc); /* The SSRC this feedback message applies to */
|
||||
res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice);
|
||||
rtcpheader = bdata;
|
||||
|
||||
ao2_lock(instance);
|
||||
res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ao2_unlock(instance);
|
||||
return;
|
||||
}
|
||||
|
||||
packet_len += res;
|
||||
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 0, htonl((2 << 30) | (AST_RTP_RTCP_FMT_REMB << 24) | (RTCP_PT_PSFB << 16) | ((remb_len/4)-1)));
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 4, htonl(rtp->ssrc));
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 8, htonl(0)); /* Per the draft, this should always be 0 */
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 12, htonl(('R' << 24) | ('E' << 16) | ('M' << 8) | ('B'))); /* Unique identifier 'R' 'E' 'M' 'B' */
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 16, htonl((1 << 24) | (feedback->remb.br_exp << 18) | (feedback->remb.br_mantissa))); /* Number of SSRCs / BR Exp / BR Mantissa */
|
||||
put_unaligned_uint32(rtcpheader + packet_len + 20, htonl(rtp->ssrc)); /* The SSRC this feedback message applies to */
|
||||
res = rtcp_sendto(instance, (unsigned int *)rtcpheader, packet_len + remb_len, 0, rtp->bundled ? remote_address : &rtp->rtcp->them, &ice);
|
||||
if (res < 0) {
|
||||
ast_log(LOG_ERROR, "RTCP PSFB transmission error: %s\n", strerror(errno));
|
||||
} else {
|
||||
ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, rtp->bundled ? *remote_address : rtp->rtcp->them, ice, sr);
|
||||
}
|
||||
|
||||
ao2_unlock(instance);
|
||||
}
|
||||
|
||||
/*! \pre instance is locked */
|
||||
|
@ -7720,10 +7784,9 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
|
|||
|
||||
memset(rtcpheader, 0, data_size);
|
||||
|
||||
res = ast_rtcp_generate_report(instance, rtcpheader, rtcp_report, &sr);
|
||||
res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
|
||||
|
||||
if (res == 0 || res == 1) {
|
||||
ast_debug(1, "Failed to add %s report to NACK, stopping here\n", sr ? "SR" : "RR");
|
||||
return &ast_null_frame;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue