mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
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
This commit is contained in:
@@ -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);
|
||||
|
Reference in New Issue
Block a user