diff options
author | Joshua Colp <jcolp@digium.com> | 2018-03-21 13:52:08 +0000 |
---|---|---|
committer | Joshua Colp <jcolp@digium.com> | 2018-03-27 08:39:00 -0600 |
commit | e14b0e960d99aaf9c75b23814a1bef22ab2a53ff (patch) | |
tree | 25a3acf7fced71385f3784401209af903a917734 /res | |
parent | a4a5b8d562b0e0f10024f7dcbfaf2cb740e81d15 (diff) |
res_rtp_asterisk: Add support for raising additional RTCP messages.
This change extends the existing AST_FRAME_RTCP frame type to be
able to contain additional RTCP message types, such as feedback
messages. The payload type is contained in the subclass which allows
knowing what is in the frame itself.
The RTCP feedback message type is now handled and REMB[1] messages
are raised with their containing information.
This also fixes a bug where all feedback messages were triggering
video updates instead of just FIR and FUR.
Finally RTCP frames are now passed up through the Asterisk core to
what is handling the channel, mapped appropriately in the case of
bridging, and written to an outgoing stream. Since RTCP frames are
on a per-stream basis this is only done on multistream capable
channels.
[1] https://tools.ietf.org/html/draft-alvestrand-rmcat-remb-03
ASTERISK-27758
ASTERISK-26366
Change-Id: I680da0ad8d5059d5e9655d896fb9d92e9da8491e
Diffstat (limited to 'res')
-rw-r--r-- | res/res_rtp_asterisk.c | 70 |
1 files changed, 59 insertions, 11 deletions
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c index d0e482405..b010f6c51 100644 --- a/res/res_rtp_asterisk.c +++ b/res/res_rtp_asterisk.c @@ -106,7 +106,7 @@ #define RTCP_PT_APP 204 /* VP8: RTCP Feedback */ /*! Payload Specific Feed Back (From RFC4585 also RFC5104) */ -#define RTCP_PT_PSFB 206 +#define RTCP_PT_PSFB AST_RTP_RTCP_PSFB #define RTP_MTU 1200 #define DTMF_SAMPLE_RATE_MS 8 /*!< DTMF samples per millisecond */ @@ -5185,6 +5185,7 @@ static const char *rtcp_payload_type2str(unsigned int pt) #define RTCP_SR_BLOCK_WORD_LENGTH 5 #define RTCP_RR_BLOCK_WORD_LENGTH 6 #define RTCP_HEADER_SSRC_LENGTH 2 +#define RTCP_FB_REMB_BLOCK_WORD_LENGTH 5 static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr) { @@ -5266,6 +5267,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup); struct ast_rtp_instance *child; struct ast_rtp *rtp; + struct ast_rtp_rtcp_feedback *feedback; i = position; first_word = ntohl(rtcpheader[i]); @@ -5284,7 +5286,15 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c min_length += (rc * RTCP_RR_BLOCK_WORD_LENGTH); break; case RTCP_PT_FUR: + break; case RTCP_PT_PSFB: + switch (rc) { + case AST_RTP_RTCP_FMT_REMB: + min_length += RTCP_FB_REMB_BLOCK_WORD_LENGTH; + break; + default: + break; + } break; case RTCP_PT_SDES: case RTCP_PT_BYE: @@ -5493,6 +5503,7 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c /* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report * object as a its data */ transport_rtp->f.frametype = AST_FRAME_RTCP; + transport_rtp->f.subclass.integer = pt; transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET; memcpy(transport_rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report)); transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report); @@ -5514,18 +5525,55 @@ static struct ast_frame *ast_rtcp_interpret(struct ast_rtp_instance *instance, c f = &transport_rtp->f; break; case RTCP_PT_FUR: - /* Handle RTCP FIR as FUR */ + /* Handle RTCP FUR as FIR by setting the format to 4 */ + rc = AST_RTP_RTCP_FMT_FIR; case RTCP_PT_PSFB: - if (rtcp_debug_test_addr(addr)) { - ast_verbose("Received an RTCP Fast Update Request\n"); + switch (rc) { + case AST_RTP_RTCP_FMT_FIR: + if (rtcp_debug_test_addr(addr)) { + ast_verbose("Received an RTCP Fast Update Request\n"); + } + transport_rtp->f.frametype = AST_FRAME_CONTROL; + transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE; + transport_rtp->f.datalen = 0; + transport_rtp->f.samples = 0; + transport_rtp->f.mallocd = 0; + transport_rtp->f.src = "RTP"; + f = &transport_rtp->f; + break; + case AST_RTP_RTCP_FMT_REMB: + /* If REMB support is not enabled ignore this message */ + if (!ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_REMB)) { + break; + } + + if (rtcp_debug_test_addr(addr)) { + ast_verbose("Received REMB report\n"); + } + transport_rtp->f.frametype = AST_FRAME_RTCP; + transport_rtp->f.subclass.integer = pt; + transport_rtp->f.stream_num = rtp->stream_num; + transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET; + feedback = transport_rtp->f.data.ptr; + feedback->fmt = rc; + + /* We don't actually care about the SSRC information in the feedback message */ + first_word = ntohl(rtcpheader[i + 2]); + feedback->remb.br_exp = (first_word >> 18) & ((1 << 6) - 1); + feedback->remb.br_mantissa = first_word & ((1 << 18) - 1); + + transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_feedback); + transport_rtp->f.offset = AST_FRIENDLY_OFFSET; + transport_rtp->f.samples = 0; + transport_rtp->f.mallocd = 0; + transport_rtp->f.delivery.tv_sec = 0; + transport_rtp->f.delivery.tv_usec = 0; + transport_rtp->f.src = "RTP"; + f = &transport_rtp->f; + break; + default: + break; } - transport_rtp->f.frametype = AST_FRAME_CONTROL; - transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE; - transport_rtp->f.datalen = 0; - transport_rtp->f.samples = 0; - transport_rtp->f.mallocd = 0; - transport_rtp->f.src = "RTP"; - f = &transport_rtp->f; break; case RTCP_PT_SDES: if (rtcp_debug_test_addr(addr)) { |