patch: add alternative protocols to sdp

- sdp_media_set_alt_protos() and accessor function


Example usage:

	err = sdp_media_set_alt_protos(m->sdp, 4,
				       "RTP/AVP",
       				       "RTP/AVPF",
       				       "RTP/SAVP",
       				       "RTP/SAVPF");
This commit is contained in:
Alfred E. Heggestad 2013-06-24 20:13:42 +00:00
parent a9a0f8459c
commit 2818fe8c1b
4 changed files with 98 additions and 5 deletions

View file

@ -87,6 +87,7 @@ struct sdp_media;
int sdp_media_add(struct sdp_media **mp, struct sdp_session *sess,
const char *name, uint16_t port, const char *proto);
int sdp_media_set_alt_protos(struct sdp_media *m, unsigned protoc, ...);
void sdp_media_set_encode_handler(struct sdp_media *m, sdp_media_enc_h *ench,
void *arg);
void sdp_media_set_fmt_ignore(struct sdp_media *m, bool fmt_ignore);
@ -101,6 +102,7 @@ void sdp_media_set_ldir(struct sdp_media *m, enum sdp_dir dir);
int sdp_media_set_lattr(struct sdp_media *m, bool replace,
const char *name, const char *value, ...);
void sdp_media_del_lattr(struct sdp_media *m, const char *name);
const char *sdp_media_proto(const struct sdp_media *m);
uint16_t sdp_media_rport(const struct sdp_media *m);
const struct sa *sdp_media_raddr(const struct sdp_media *m);
void sdp_media_raddr_rtcp(const struct sdp_media *m, struct sa *raddr);

View file

@ -18,6 +18,7 @@
static void destructor(void *arg)
{
struct sdp_media *m = arg;
unsigned i;
list_flush(&m->lfmtl);
list_flush(&m->rfmtl);
@ -31,6 +32,9 @@ static void destructor(void *arg)
return;
}
for (i=0; i<ARRAY_SIZE(m->protov); i++)
mem_deref(m->protov[i]);
list_unlink(&m->le);
mem_deref(m->name);
mem_deref(m->proto);
@ -171,18 +175,57 @@ void sdp_media_rreset(struct sdp_media *m)
}
/**
* Compare media line protocols
*
* @param m SDP Media line
* @param proto Transport protocol
* @param update Update media protocol if match is found in alternate set
*
* @return True if matching, False if not
*/
bool sdp_media_proto_cmp(struct sdp_media *m, const struct pl *proto,
bool update)
{
unsigned i;
if (!m || !proto)
return false;
if (!pl_strcmp(proto, m->proto))
return true;
for (i=0; i<ARRAY_SIZE(m->protov); i++) {
if (!m->protov[i] || pl_strcmp(proto, m->protov[i]))
continue;
if (update) {
mem_deref(m->proto);
m->proto = mem_ref(m->protov[i]);
}
return true;
}
return false;
}
/**
* Find an SDP Media line from name and transport protocol
*
* @param sess SDP Session
* @param name Media name
* @param proto Transport protocol
* @param update_proto Update media transport protocol
*
* @return Matching media line if found, NULL if not found
*/
struct sdp_media *sdp_media_find(const struct sdp_session *sess,
const struct pl *name,
const struct pl *proto)
const struct pl *proto,
bool update_proto)
{
struct le *le;
@ -196,7 +239,7 @@ struct sdp_media *sdp_media_find(const struct sdp_session *sess,
if (pl_strcmp(name, m->name))
continue;
if (pl_strcmp(proto, m->proto))
if (!sdp_media_proto_cmp(m, proto, update_proto))
continue;
return m;
@ -290,6 +333,44 @@ void sdp_media_align_formats(struct sdp_media *m, bool offer)
}
/**
* Set alternative protocols for an SDP Media line
*
* @param m SDP Media line
* @param protoc Number of alternative protocols
*
* @return 0 if success, otherwise errorcode
*/
int sdp_media_set_alt_protos(struct sdp_media *m, unsigned protoc, ...)
{
const char *proto;
int err = 0;
unsigned i;
va_list ap;
if (!m)
return EINVAL;
va_start(ap, protoc);
for (i=0; i<ARRAY_SIZE(m->protov); i++) {
m->protov[i] = mem_deref(m->protov[i]);
if (i >= protoc)
continue;
proto = va_arg(ap, const char *);
if (proto)
err |= str_dup(&m->protov[i], proto);
}
va_end(ap);
return err;
}
/**
* Set SDP Media line encode handler
*
@ -475,6 +556,12 @@ void sdp_media_del_lattr(struct sdp_media *m, const char *name)
}
const char *sdp_media_proto(const struct sdp_media *m)
{
return m ? m->proto : NULL;
}
/**
* Get the remote port number of an SDP Media line
*

View file

@ -181,7 +181,7 @@ static int media_decode(struct sdp_media **mp, struct sdp_session *sess,
if (!offer)
return EPROTO;
m = sdp_media_find(sess, &name, &proto);
m = sdp_media_find(sess, &name, &proto, true);
if (!m) {
err = sdp_media_radd(&m, sess, &name, &proto);
if (err)
@ -196,7 +196,7 @@ static int media_decode(struct sdp_media **mp, struct sdp_session *sess,
if (pl_strcmp(&name, m->name))
return offer ? ENOTSUP : EPROTO;
if (pl_strcmp(&proto, m->proto))
if (!sdp_media_proto_cmp(m, &proto, offer))
return ENOTSUP;
}

View file

@ -39,6 +39,7 @@ struct sdp_media {
int32_t rbwv[SDP_BANDWIDTH_MAX];
char *name;
char *proto;
char *protov[8];
sdp_media_enc_h *ench;
void *arg;
enum sdp_dir ldir;
@ -57,9 +58,12 @@ void sdp_session_rreset(struct sdp_session *sess);
int sdp_media_radd(struct sdp_media **mp, struct sdp_session *sess,
const struct pl *name, const struct pl *proto);
void sdp_media_rreset(struct sdp_media *m);
bool sdp_media_proto_cmp(struct sdp_media *m, const struct pl *proto,
bool update);
struct sdp_media *sdp_media_find(const struct sdp_session *sess,
const struct pl *name,
const struct pl *proto);
const struct pl *proto,
bool update_proto);
void sdp_media_align_formats(struct sdp_media *m, bool offer);