Add required items for Google video support.

This adds legacy STUN support for RTCP sockets, adds RTCP candidates to the Google transport information, and adds required codec parameters.

(closes issue ASTERISK-20106)
Reported by: Malcolm Davenport


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@369864 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Joshua Colp
2012-07-10 11:49:18 +00:00
parent 8f162be802
commit 7296b670d4
2 changed files with 56 additions and 5 deletions

View File

@@ -820,12 +820,15 @@ static int jingle_add_google_candidates_to_transport(struct ast_rtp_instance *rt
break;
}
/* We only support RTP candidates */
if (candidate->id != 1) {
if (candidate->id == 1) {
iks_insert_attrib(local_candidate, "name", !video ? "rtp" : "video_rtp");
} else if (candidate->id == 2) {
iks_insert_attrib(local_candidate, "name", !video ? "rtcp" : "video_rtcp");
} else {
iks_delete(local_candidate);
continue;
}
iks_insert_attrib(local_candidate, "name", !video ? "rtp" : "video_rtp");
iks_insert_attrib(local_candidate, "address", ast_sockaddr_stringify_host(&candidate->address));
iks_insert_attrib(local_candidate, "port", ast_sockaddr_stringify_port(&candidate->address));
@@ -1150,6 +1153,27 @@ static int jingle_add_payloads_to_description(struct jingle_session *session, st
iks_insert_attrib(payload, "clockrate", tmp);
}
if ((type == AST_FORMAT_TYPE_VIDEO) && (session->transport == JINGLE_TRANSPORT_GOOGLE_V2)) {
iks *parameter;
/* Google requires these parameters to be set, but alas we can not give accurate values so use some safe defaults */
if ((parameter = iks_new("parameter"))) {
iks_insert_attrib(parameter, "name", "width");
iks_insert_attrib(parameter, "value", "640");
iks_insert_node(payload, parameter);
}
if ((parameter = iks_new("parameter"))) {
iks_insert_attrib(parameter, "name", "height");
iks_insert_attrib(parameter, "value", "480");
iks_insert_node(payload, parameter);
}
if ((parameter = iks_new("parameter"))) {
iks_insert_attrib(parameter, "name", "framerate");
iks_insert_attrib(parameter, "value", "30");
iks_insert_node(payload, parameter);
}
}
iks_insert_node(description, payload);
payloads[i++] = payload;
}
@@ -2010,6 +2034,11 @@ static int jingle_interpret_google_transport(struct jingle_session *session, iks
continue;
}
/* We only permit audio and video, not RTCP */
if (strcasecmp(name, "rtp") && strcasecmp(name, "video_rtp")) {
continue;
}
/* Parse the target information so we can send a STUN request to the candidate */
if (sscanf(port, "%30d", &real_port) != 1) {
jingle_queue_hangup_with_cause(session, AST_CAUSE_PROTOCOL_ERROR);

View File

@@ -2421,14 +2421,14 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
{
struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
struct ast_sockaddr addr;
unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET];
unsigned char rtcpdata[8192 + AST_FRIENDLY_OFFSET];
unsigned int *rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
int res, packetwords, position = 0;
struct ast_frame *f = &ast_null_frame;
/* Read in RTCP data from the socket */
if ((res = rtcp_recvfrom(instance, rtcpdata + AST_FRIENDLY_OFFSET,
sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
sizeof(rtcpdata) - AST_FRIENDLY_OFFSET,
0, &addr)) < 0) {
ast_assert(errno != EBADF);
if (errno != EAGAIN) {
@@ -2443,6 +2443,28 @@ static struct ast_frame *ast_rtcp_read(struct ast_rtp_instance *instance)
return &ast_null_frame;
}
if (!*(rtcpdata + AST_FRIENDLY_OFFSET)) {
struct sockaddr_in addr_tmp;
struct ast_sockaddr addr_v4;
if (ast_sockaddr_is_ipv4(&addr)) {
ast_sockaddr_to_sin(&addr, &addr_tmp);
} else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
ast_debug(1, "Using IPv6 mapped address %s for STUN\n",
ast_sockaddr_stringify(&addr));
ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
} else {
ast_debug(1, "Cannot do STUN for non IPv4 address %s\n",
ast_sockaddr_stringify(&addr));
return &ast_null_frame;
}
if ((ast_stun_handle_packet(rtp->rtcp->s, &addr_tmp, rtcpdata + AST_FRIENDLY_OFFSET, res, NULL, NULL) == AST_STUN_ACCEPT)) {
ast_sockaddr_from_sin(&addr, &addr_tmp);
ast_sockaddr_copy(&rtp->rtcp->them, &addr);
}
return &ast_null_frame;
}
packetwords = res / 4;
if (ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT)) {