[asterisk-commits] kharwell: branch kharwell/pimp_sip_video r383498 - in /team/kharwell/pimp_sip...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Mar 20 16:54:47 CDT 2013
Author: kharwell
Date: Wed Mar 20 16:54:46 2013
New Revision: 383498
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=383498
Log:
video for chan_gulp - initial review
Modified:
team/kharwell/pimp_sip_video/channels/chan_gulp.c
team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c
Modified: team/kharwell/pimp_sip_video/channels/chan_gulp.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/channels/chan_gulp.c?view=diff&rev=383498&r1=383497&r2=383498
==============================================================================
--- team/kharwell/pimp_sip_video/channels/chan_gulp.c (original)
+++ team/kharwell/pimp_sip_video/channels/chan_gulp.c Wed Mar 20 16:54:46 2013
@@ -314,7 +314,7 @@
pvt->media[SIP_MEDIA_VIDEO] = ao2_find(session->media, "video", OBJ_KEY);
ast_channel_tech_pvt_set(chan, pvt);
- ast_format_cap_copy(ast_channel_nativeformats(chan), session->caps); /* session->endpoint->codecs); */
+ ast_format_cap_copy(ast_channel_nativeformats(chan), session->caps);
ast_codec_choose(&session->endpoint->prefs, session->endpoint->codecs, 1, &fmt);
ast_format_copy(ast_channel_writeformat(chan), &fmt);
@@ -560,7 +560,6 @@
}
packet->msg->body = pjsip_msg_body_create(packet->pool, &type, &subtype, &xml);
- /* ast_sip_session_send_request(session, packet); */
return 0;
}
Modified: team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c
URL: http://svnview.digium.com/svn/asterisk/team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c?view=diff&rev=383498&r1=383497&r2=383498
==============================================================================
--- team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c (original)
+++ team/kharwell/pimp_sip_video/res/res_sip_sdp_video.c Wed Mar 20 16:54:46 2013
@@ -16,13 +16,6 @@
* at the top of the source tree.
*/
-/*! \file
- *
- * \author Kevin Harwell <kharwell at digium.com>
- *
- * \brief SIP SDP 'video' media stream handling
- */
-
/*** MODULEINFO
<depend>res_sip</depend>
<depend>res_sip_session</depend>
@@ -55,21 +48,6 @@
/*! \brief Scheduler for RTCP purposes */
static struct ast_sched_context *sched;
-/*! \brief Forward declarations for SDP handler functions */
-static int video_negotiate_incoming_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *sdp, const struct pjmedia_sdp_media *stream);
-static int video_create_outgoing_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, struct pjmedia_sdp_session *sdp);
-static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream);
-static void video_stream_destroy(struct ast_sip_session_media *session_media);
-
-/*! \brief SDP handler for 'video' media stream */
-static struct ast_sip_session_sdp_handler video_sdp_handler = {
- .id = STR_VIDEO,
- .negotiate_incoming_sdp_stream = video_negotiate_incoming_sdp_stream,
- .create_outgoing_sdp_stream = video_create_outgoing_sdp_stream,
- .apply_negotiated_sdp_stream = video_apply_negotiated_sdp_stream,
- .stream_destroy = video_stream_destroy,
-};
-
/*! \brief Internal function which creates an RTP instance */
static int video_create_rtp(struct ast_sip_session *session, struct ast_sip_session_media *session_media, unsigned int ipv6)
{
@@ -100,7 +78,8 @@
return 0;
}
-static void get_peer_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, struct ast_rtp_codecs *codecs, const char *type)
+static void get_codecs(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream,
+ struct ast_rtp_codecs* codecs, const char *type)
{
pjmedia_sdp_attr *attr;
int i, num = 0;
@@ -136,60 +115,90 @@
}
}
-static int get_peer_caps(struct ast_sip_session *session, const struct pjmedia_sdp_media *stream, const char *type)
-{
+static int set_caps(struct ast_sip_session *session, struct ast_sip_session_media *session_media,
+ const struct pjmedia_sdp_media *stream, enum ast_format_type type, const char *type_desc)
+{
+ RAII_VAR(struct ast_format_cap *, caps, NULL, ast_format_cap_destroy);
+ RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+ RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
struct ast_rtp_codecs codecs;
- RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
+ struct ast_format fmt;
int fmts = 0;
- if (!(peer = ast_format_cap_alloc_nolock())) {
- ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type);
- return -1;
- }
-
- get_peer_codecs(session, stream, &codecs, type);
+ if (!(caps = ast_format_cap_alloc_nolock()) ||
+ !(peer = ast_format_cap_alloc_nolock())) {
+ ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type_desc);
+ return -1;
+ }
+
+ /* get the endpoint capabilities */
+ ast_format_cap_copy(caps, session->endpoint->codecs);
+ ast_format_cap_remove_bytype(caps, AST_FORMAT_TYPE_AUDIO);
+
+ /* get the capabilities on the peer */
+ get_codecs(session, stream, &codecs, type_desc);
ast_rtp_codecs_payload_formats(&codecs, peer, &fmts);
- ast_format_cap_append(session->caps, peer);
- ast_rtp_codecs_payloads_destroy(&codecs);
-
- return 1;
-}
-
-static struct ast_format_cap* get_joint_caps(struct ast_sip_session *session, const struct ast_format_cap *caps,
- const char *type, enum ast_format_type remove_fmt)
-{
- RAII_VAR(struct ast_format_cap *, conf, NULL, ast_format_cap_destroy);
- RAII_VAR(struct ast_format_cap *, peer, NULL, ast_format_cap_destroy);
- struct ast_format_cap *joint;
-
- if (!(conf = ast_format_cap_alloc_nolock()) ||
- !(peer = ast_format_cap_alloc_nolock())) {
- ast_log(LOG_ERROR, "Failed to allocate %s capabilities\n", type);
- return NULL;
- }
-
- ast_format_cap_copy(conf, session->endpoint->codecs);
- ast_format_cap_remove_bytype(conf, remove_fmt);
-
- ast_format_cap_copy(peer, caps);
- ast_format_cap_remove_bytype(peer, remove_fmt);
-
- /* ast_format_cap_joint_copy */
- if (!(joint = ast_format_cap_joint(conf, peer))) {
+ /* get the joint capabilities between peer and endpoint */
+ if (!(joint = ast_format_cap_joint(caps, peer))) {
char usbuf[64], thembuf[64];
+ ast_rtp_codecs_payloads_destroy(&codecs);
if (session->channel) {
ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
}
- ast_getformatname_multiple(usbuf, sizeof(usbuf), conf);
+ ast_getformatname_multiple(usbuf, sizeof(usbuf), caps);
ast_getformatname_multiple(thembuf, sizeof(thembuf), peer);
ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
- return NULL;
- }
-
- return joint;
+ return -1;
+ }
+
+ ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
+ session_media->rtp);
+
+ ast_format_cap_copy(caps, session->caps);
+ ast_format_cap_remove_bytype(caps, type);
+ ast_format_cap_append(caps, joint);
+ ast_format_cap_append(session->caps, joint);
+
+ if (session->channel) {
+ /* Apply the new formats to the channel, potentially changing read/write formats while doing so */
+ ast_format_cap_append(ast_channel_nativeformats(session->channel), session->caps);
+ ast_codec_choose(&session->endpoint->prefs, caps, 0, &fmt);
+ ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
+ ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
+ ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
+ ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+ }
+
+ ast_rtp_codecs_payloads_destroy(&codecs);
+ return 1;
+}
+
+static pjmedia_sdp_attr* generate_fmtp_attr(pj_pool_t *pool, struct ast_format *format, int rtp_code)
+{
+ struct ast_str *fmtp0 = ast_str_alloca(256);
+ pj_str_t fmtp1;
+ pjmedia_sdp_attr *attr = NULL;
+ char *tmp;
+
+ ast_format_sdp_generate(format, rtp_code, &fmtp0);
+ if (ast_str_strlen(fmtp0)) {
+ tmp = ast_str_buffer(fmtp0) + ast_str_strlen(fmtp0) - 1;
+ /* remove any carriage return line feeds */
+ while (*tmp == '\r' || *tmp == '\n') --tmp;
+ *++tmp = '\0';
+ /* ast...generate gives us everything, just need value */
+ tmp = strchr(ast_str_buffer(fmtp0), ':');
+ if (tmp && tmp+1) {
+ fmtp1 = pj_str(tmp+1);
+ } else {
+ fmtp1 = pj_str(ast_str_buffer(fmtp0));
+ }
+ attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1);
+ }
+ return attr;
}
/*! \brief Function which negotiates an incoming 'video' stream */
@@ -215,8 +224,9 @@
if (!session_media->rtp && video_create_rtp(session, session_media, ast_sockaddr_is_ipv6(addrs))) {
return -1;
}
+
/* pjmedia takes care of the formats and such */
- return get_peer_caps(session, stream, STR_VIDEO);
+ return set_caps(session, session_media, stream, AST_FORMAT_TYPE_VIDEO, STR_VIDEO);
}
/*! \brief Function which creates an outgoing 'video' stream */
@@ -231,13 +241,12 @@
pj_pool_t *pool = session->inv_session->pool_active;
pjmedia_sdp_media *media;
struct ast_sockaddr addr;
-
int rtp_code0;
char rtp_code1[32];
- struct ast_str *fmtp0 = ast_str_alloca(256);
- pj_str_t fmtp1;
pjmedia_sdp_rtpmap rtpmap;
pjmedia_sdp_attr *attr;
+ struct ast_format format;
+ RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
if (!ast_format_cap_has_type(session->endpoint->codecs, AST_FORMAT_TYPE_VIDEO)) {
/* If no video formats are configured don't add a stream */
@@ -265,26 +274,22 @@
media->desc.port = (pj_uint16_t) ast_sockaddr_port(&addr);
media->desc.port_count = 1;
- struct ast_format format;
- RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
-
- if (!ast_format_cap_is_empty(session->caps)) {
- joint = get_joint_caps(session, session->caps, "video", AST_FORMAT_TYPE_AUDIO);
- }
-
- if (!joint) {
- if (!(joint = ast_format_cap_alloc_nolock())) {
- ast_log(LOG_ERROR, "Failed to allocate video capabilities\n");
- return -1;
- }
+ if (!(joint = ast_format_cap_alloc_nolock())) {
+ ast_log(LOG_ERROR, "Failed to allocate video capabilities\n");
+ return -1;
+ }
+ if (ast_format_cap_is_empty(session->caps)) {
ast_format_cap_copy(joint, session->endpoint->codecs);
+ } else {
+ ast_format_cap_copy(joint, session->caps);
}
ast_format_cap_iter_start(joint);
while (!(ast_format_cap_iter_next(joint, &format))) {
- /* if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) { */
- /* continue; */
- /* } */
+ if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) {
+ continue;
+ }
+
if ((rtp_code0 = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(session_media->rtp), 1, &format, 0)) == -1) {
return -1;
}
@@ -299,12 +304,8 @@
pjmedia_sdp_rtpmap_to_attr(pool, &rtpmap, &attr);
media->attr[media->attr_count++] = attr;
- ast_format_sdp_generate(&format, rtp_code0, &fmtp0);
- if (ast_str_strlen(fmtp0)) {
- fmtp1 = pj_str(ast_str_buffer(fmtp0));
- if ((attr = pjmedia_sdp_attr_create(pool, "fmtp", &fmtp1))) {
- media->attr[media->attr_count++] = attr;
- }
+ if ((attr = generate_fmtp_attr(pool, &format, rtp_code0))) {
+ media->attr[media->attr_count++] = attr;
}
}
ast_format_cap_iter_end(joint);
@@ -323,15 +324,10 @@
/*! \brief Function which applies a negotiated SDP stream */
static int video_apply_negotiated_sdp_stream(struct ast_sip_session *session, struct ast_sip_session_media *session_media, const struct pjmedia_sdp_session *local, const struct pjmedia_sdp_media *local_stream, const struct pjmedia_sdp_session *remote, const struct pjmedia_sdp_media *remote_stream)
{
- int format, othercapability = 0;
char host[NI_MAXHOST];
RAII_VAR(struct ast_sockaddr *, addrs, NULL, ast_free_ptr);
- struct ast_rtp_codecs codecs;
- const pjmedia_sdp_attr *attr;
- RAII_VAR(struct ast_format_cap *, cap, NULL, ast_format_cap_destroy);
- RAII_VAR(struct ast_format_cap *, jointcap, NULL, ast_format_cap_destroy);
- RAII_VAR(struct ast_format_cap *, peercap, NULL, ast_format_cap_destroy);
- struct ast_format fmt;
+
+ RAII_VAR(struct ast_format_cap *, joint, NULL, ast_format_cap_destroy);
/* Create an RTP instance if need be */
if (!session_media->rtp && video_create_rtp(session, session_media, session->endpoint->rtp_ipv6)) {
@@ -346,77 +342,17 @@
return -1;
}
- /* To properly apply formats to the channel we need to keep track of capabilities */
- if (!(cap = ast_format_cap_alloc_nolock()) ||
- !(peercap = ast_format_cap_alloc_nolock())) {
- ast_log(LOG_ERROR, "Failed to allocate video capabilities\n");
- return -1;
- }
-
/* Apply connection information to the RTP instance */
ast_sockaddr_set_port(addrs, remote_stream->desc.port);
ast_rtp_instance_set_remote_address(session_media->rtp, addrs);
- ast_rtp_codecs_payloads_initialize(&codecs);
-
- /* Iterate through provided formats */
- for (format = 0; format < local_stream->desc.fmt_count; format++) {
- /* The payload is kept as a string for things like t38 but for video it is always numerical */
- ast_rtp_codecs_payloads_set_m_type(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]));
-
- /* Look for the optional rtpmap attribute */
- if ((attr = pjmedia_sdp_media_find_attr2(local_stream, "rtpmap", &local_stream->desc.fmt[format]))) {
- pjmedia_sdp_rtpmap *rtpmap;
-
- /* Interpret the attribute as an rtpmap */
- if ((pjmedia_sdp_attr_to_rtpmap(session->inv_session->pool_active, attr, &rtpmap)) == PJ_SUCCESS) {
- char name[32];
-
- ast_copy_pj_str(name, &rtpmap->enc_name, sizeof(name));
- ast_rtp_codecs_payloads_set_rtpmap_type_rate(&codecs, NULL, pj_strtoul(&local_stream->desc.fmt[format]),
- "video", name, 0, rtpmap->clock_rate);
- }
- }
- }
-
- ast_rtp_codecs_payload_formats(&codecs, peercap, &othercapability);
-
- /* Using the configured codecs and the codecs in this SDP we determine the joint formats for *video only* */
- ast_format_cap_copy(cap, session->endpoint->codecs);
- ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
-
- if (!(jointcap = ast_format_cap_joint(cap, peercap))) {
- char usbuf[64], thembuf[64];
-
- ast_channel_hangupcause_set(session->channel, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
- ast_getformatname_multiple(usbuf, sizeof(usbuf), cap);
- ast_getformatname_multiple(thembuf, sizeof(thembuf), peercap);
- ast_log(LOG_WARNING, "No joint capabilities between our configuration(%s) and incoming SDP(%s)\n", usbuf, thembuf);
-
- ast_rtp_codecs_payloads_destroy(&codecs);
- return -1;
- }
-
- ast_rtp_codecs_payloads_copy(&codecs, ast_rtp_instance_get_codecs(session_media->rtp),
- session_media->rtp);
-
- /* Now that we have joint formats for video remove the existing ones from the channel and add the new ones */
- ast_format_cap_copy(cap, ast_channel_nativeformats(session->channel));
- ast_format_cap_remove_bytype(cap, AST_FORMAT_TYPE_AUDIO);
- ast_format_cap_append(cap, jointcap);
-
- /* Apply the new formats to the channel, potentially changing read/write formats while doing so */
- ast_format_cap_append(ast_channel_nativeformats(session->channel), cap);
- ast_codec_choose(&session->endpoint->prefs, cap, 0, &fmt);
- ast_format_copy(ast_channel_rawwriteformat(session->channel), &fmt);
- ast_format_copy(ast_channel_rawreadformat(session->channel), &fmt);
- ast_set_read_format(session->channel, ast_channel_readformat(session->channel));
- ast_set_write_format(session->channel, ast_channel_writeformat(session->channel));
+ if (set_caps(session, session_media, local_stream, AST_FORMAT_TYPE_VIDEO, STR_VIDEO) < 1) {
+ return -1;
+ }
ast_channel_set_fd(session->channel, 2, ast_rtp_instance_fd(session_media->rtp, 0));
ast_channel_set_fd(session->channel, 3, ast_rtp_instance_fd(session_media->rtp, 1));
- ast_rtp_codecs_payloads_destroy(&codecs);
return 1;
}
@@ -430,6 +366,15 @@
ast_rtp_instance_stop(session_media->rtp);
ast_rtp_instance_destroy(session_media->rtp);
}
+
+/*! \brief SDP handler for 'video' media stream */
+static struct ast_sip_session_sdp_handler video_sdp_handler = {
+ .id = STR_VIDEO,
+ .negotiate_incoming_sdp_stream = video_negotiate_incoming_sdp_stream,
+ .create_outgoing_sdp_stream = video_create_outgoing_sdp_stream,
+ .apply_negotiated_sdp_stream = video_apply_negotiated_sdp_stream,
+ .stream_destroy = video_stream_destroy,
+};
static int incoming_request(struct ast_sip_session *session, struct pjsip_rx_data *rdata)
{
@@ -468,7 +413,7 @@
goto end;
}
- if (ast_sip_session_register_sdp_handler(&video_sdp_handler, "video")) {
+ if (ast_sip_session_register_sdp_handler(&video_sdp_handler, STR_VIDEO)) {
ast_log(LOG_ERROR, "Unable to register SDP handler for 'video' stream type\n");
goto end;
}
@@ -488,7 +433,7 @@
static int unload_module(void)
{
ast_sip_session_unregister_supplement(&info_supplement);
- ast_sip_session_unregister_sdp_handler(&video_sdp_handler, "video");
+ ast_sip_session_unregister_sdp_handler(&video_sdp_handler, STR_VIDEO);
ast_sched_context_destroy(sched);
return 0;
}
More information about the asterisk-commits
mailing list