Merge "res_rtp_asterisk: Add support for raising additional RTCP messages."

changes/05/8705/1
Kevin Harwell 8 years ago committed by Gerrit Code Review
commit 48ef239a01

@ -965,6 +965,8 @@ static int chan_pjsip_write_stream(struct ast_channel *ast, int stream_num, stru
break;
case AST_FRAME_CNG:
break;
case AST_FRAME_RTCP:
break;
default:
ast_log(LOG_WARNING, "Can't send %u type frames with PJSIP\n", frame->frametype);
break;

@ -372,6 +372,11 @@ static void lintospeex_feedback(struct ast_trans_pvt *pvt, struct ast_frame *fee
if(!exp_rtcp_fb)
return;
/* We only accept feedback information in the form of SR and RR reports */
if (feedback->subclass.integer != AST_RTP_RTCP_SR && feedback->subclass.integer != AST_RTP_RTCP_RR) {
return;
}
rtcp_report = (struct ast_rtp_rtcp_report *)feedback->data.ptr;
if (rtcp_report->reception_report_count == 0)
return;

@ -127,7 +127,7 @@ enum ast_frame_type {
* directly into bridges.
*/
AST_FRAME_BRIDGE_ACTION_SYNC,
/*! RTCP feedback */
/*! RTCP feedback (the subclass will contain the payload type) */
AST_FRAME_RTCP,
};
#define AST_FRAME_DTMF AST_FRAME_DTMF_END

@ -292,6 +292,14 @@ struct ast_rtp_payload_type {
#define AST_RTP_RTCP_SR 200
/*! Receiver Report */
#define AST_RTP_RTCP_RR 201
/*! Payload Specific Feed Back (From RFC4585 also RFC5104) */
#define AST_RTP_RTCP_PSFB 206
/* Common RTCP feedback message types */
/*! Full INTRA-frame Request (From RFC5104) */
#define AST_RTP_RTCP_FMT_FIR 4
/*! REMB Information (From draft-alvestrand-rmcat-remb-03) */
#define AST_RTP_RTCP_FMT_REMB 15
/*!
* \since 12
@ -327,6 +335,24 @@ struct ast_rtp_rtcp_report {
struct ast_rtp_rtcp_report_block *report_block[0];
};
/*!
* \since 15.4.0
* \brief A REMB feedback message (see draft-alvestrand-rmcat-remb-03 for details) */
struct ast_rtp_rtcp_feedback_remb {
unsigned int br_exp; /*!< Exponential scaling of the mantissa for the maximum total media bit rate value */
unsigned int br_mantissa; /*!< The mantissa of the maximum total media bit rate */
};
/*!
* \since 15.4.0
* \brief An object that represents data received in a feedback report */
struct ast_rtp_rtcp_feedback {
unsigned int fmt; /*!< The feedback message type */
union {
struct ast_rtp_rtcp_feedback_remb remb; /*!< REMB feedback information */
};
};
/*! Structure that represents statistics from an RTP instance */
struct ast_rtp_instance_stats {
/*! Number of packets transmitted */

@ -653,7 +653,8 @@ static int bridge_channel_write_frame(struct ast_bridge_channel *bridge_channel,
case AST_FRAME_VIDEO:
case AST_FRAME_TEXT:
case AST_FRAME_IMAGE:
/* Media frames need to be mapped to an appropriate write stream */
case AST_FRAME_RTCP:
/* These frames need to be mapped to an appropriate write stream */
if (frame->stream_num < 0) {
/* Map to default stream */
frame->stream_num = -1;

@ -4123,8 +4123,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio, int
if (ast_channel_writetrans(chan)) {
ast_translate(ast_channel_writetrans(chan), f, 0);
}
ast_frfree(f);
f = &ast_null_frame;
break;
default:
/* Just pass it on! */
break;
@ -5267,6 +5266,14 @@ int ast_write_stream(struct ast_channel *chan, int stream_num, struct ast_frame
/* Ignore these */
res = 0;
break;
case AST_FRAME_RTCP:
/* RTCP information is on a per-stream basis and only available on multistream capable channels */
if (ast_channel_tech(chan)->write_stream && stream) {
res = ast_channel_tech(chan)->write_stream(chan, ast_stream_get_position(stream), fr);
} else {
res = 0;
}
break;
default:
/* At this point, fr is the incoming frame and f is NULL. Channels do
* not expect to get NULL as a frame pointer and will segfault. Hence,

@ -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)) {

Loading…
Cancel
Save