summaryrefslogtreecommitdiff
path: root/res/res_rtp_asterisk.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-08-23 15:42:27 +0000
committerMatthew Jordan <mjordan@digium.com>2013-08-23 15:42:27 +0000
commit4d348e853cbd9ba7bc976487bfcb352a84e5ece0 (patch)
treefdf289e34cd706884aed7a262409fc3cdcba9bd1 /res/res_rtp_asterisk.c
parente31bd332b83f0245ce8bd6626279e1b9c683ec18 (diff)
Add pass through support for Opus and VP8; Opus format attribute negotiation
This patch adds pass through support for Opus and VP8. That includes: * Format attribute negotiation for Opus. Note that unlike some other codecs, the draft RFC specifies having spaces delimiting the attributes in addition to ';', so you have "attra=X; attrb=Y". This broke the attribute parsing in chan_sip, so a small tweak was also included in this patch for that. * A format attribute negotiation module for Opus, res_format_attr_opus * Fast picture update for VP8. Since VP8 uses a different RTCP packet number than FIR, this really is specific to VP8 at this time. Note that the format attribute negotiation in res_pjsip_sdp_rtp was written by mjordan. The rest of this patch was written completely by Lorenzo Miniero. Review: https://reviewboard.asterisk.org/r/2723/ (closes issue ASTERISK-21981) Reported by: Tzafrir Cohen patches: asterisk_opus+vp8_passthrough_20130718.patch uploaded by lminiero (License 6518) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@397526 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_rtp_asterisk.c')
-rw-r--r--res/res_rtp_asterisk.c54
1 files changed, 51 insertions, 3 deletions
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index db07e4ec5..6383b09e3 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -90,6 +90,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define RTCP_PT_SDES 202
#define RTCP_PT_BYE 203
#define RTCP_PT_APP 204
+/* VP8: RTCP Feedback */
+#define RTCP_PT_PSFB 206
#define RTP_MTU 1200
@@ -350,6 +352,9 @@ struct ast_rtcp {
double normdevrtt;
double stdevrtt;
unsigned int rtt_count;
+
+ /* VP8: sequence number for the RTCP FIR FCI */
+ int firseq;
};
struct rtp_red {
@@ -2414,7 +2419,7 @@ static int ast_rtcp_write(const void *data)
}
if (!res) {
- /*
+ /*
* Not being rescheduled.
*/
ao2_ref(instance, -1);
@@ -2609,6 +2614,45 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
return 0;
}
+ /* VP8: is this a request to send a RTCP FIR? */
+ if (frame->frametype == AST_FRAME_CONTROL && frame->subclass.integer == AST_CONTROL_VIDUPDATE) {
+ struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
+ unsigned int *rtcpheader;
+ char bdata[1024];
+ int len = 20;
+ int ice;
+ int res;
+
+ if (!rtp || !rtp->rtcp) {
+ return 0;
+ }
+
+ if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
+ /*
+ * RTCP was stopped.
+ */
+ return 0;
+ }
+
+ /* Prepare RTCP FIR (PT=206, FMT=4) */
+ rtp->rtcp->firseq++;
+ if(rtp->rtcp->firseq == 256) {
+ 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->rtcp->them, &ice);
+ if (res < 0) {
+ ast_log(LOG_ERROR, "RTCP FIR transmission error: %s\n", strerror(errno));
+ }
+ return 0;
+ }
+
/* If there is no data length we can't very well send the packet */
if (!frame->datalen) {
ast_debug(1, "Received frame with no data for RTP instance '%p' so dropping frame\n", instance);
@@ -2660,6 +2704,8 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
case AST_FORMAT_SIREN7:
case AST_FORMAT_SIREN14:
case AST_FORMAT_G719:
+ /* Opus */
+ case AST_FORMAT_OPUS:
/* these are all frame-based codecs and cannot be safely run through
a smoother */
break;
@@ -3353,6 +3399,8 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
message_blob);
break;
case RTCP_PT_FUR:
+ /* Handle RTCP FIR as FUR */
+ case RTCP_PT_PSFB:
if (rtcp_debug_test_addr(&addr)) {
ast_verbose("Received an RTCP Fast Update Request\n");
}
@@ -4174,14 +4222,14 @@ static int ast_rtp_sendcng(struct ast_rtp_instance *instance, int level)
payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 0, NULL, AST_RTP_CN);
level = 127 - (level & 0x7f);
-
+
rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
/* Get a pointer to the header */
rtpheader = (unsigned int *)data;
rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
rtpheader[1] = htonl(rtp->lastts);
- rtpheader[2] = htonl(rtp->ssrc);
+ rtpheader[2] = htonl(rtp->ssrc);
data[12] = level;
res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 1, 0, &remote_address, &ice);