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:
parent
a9a0f8459c
commit
2818fe8c1b
4 changed files with 98 additions and 5 deletions
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
*
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue