Squashed 'third_party/rawrtc/re/' content from commit f3163ce8b
Change-Id: I6a235e6ac0f03269d951026f9d195da05c40fdab
git-subtree-dir: third_party/rawrtc/re
git-subtree-split: f3163ce8b526a13b35ef71ce4dd6f43585064d8a
diff --git a/src/sdp/format.c b/src/sdp/format.c
new file mode 100644
index 0000000..9cc9dd9
--- /dev/null
+++ b/src/sdp/format.c
@@ -0,0 +1,266 @@
+/**
+ * @file sdp/format.c SDP format
+ *
+ * Copyright (C) 2010 Creytiv.com
+ */
+#include <stdlib.h>
+#include <string.h>
+#include <re_types.h>
+#include <re_fmt.h>
+#include <re_mem.h>
+#include <re_mbuf.h>
+#include <re_list.h>
+#include <re_sa.h>
+#include <re_sdp.h>
+#include "sdp.h"
+
+
+static void destructor(void *arg)
+{
+ struct sdp_format *fmt = arg;
+
+ list_unlink(&fmt->le);
+
+ if (fmt->ref)
+ mem_deref(fmt->data);
+
+ mem_deref(fmt->id);
+ mem_deref(fmt->params);
+ mem_deref(fmt->rparams);
+ mem_deref(fmt->name);
+}
+
+
+/**
+ * Add an SDP Format to an SDP Media line
+ *
+ * @param fmtp Pointer to allocated SDP Format
+ * @param m SDP Media line
+ * @param prepend True to prepend, False to append
+ * @param id Format identifier
+ * @param name Format name
+ * @param srate Sampling rate
+ * @param ch Number of channels
+ * @param ench Optional format encode handler
+ * @param cmph Optional format comparison handler
+ * @param data Opaque data for handler
+ * @param ref True to mem_ref() data
+ * @param params Formatted parameters
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_format_add(struct sdp_format **fmtp, struct sdp_media *m,
+ bool prepend, const char *id, const char *name,
+ uint32_t srate, uint8_t ch, sdp_fmtp_enc_h *ench,
+ sdp_fmtp_cmp_h *cmph, void *data, bool ref,
+ const char *params, ...)
+{
+ struct sdp_format *fmt;
+ int err;
+
+ if (!m)
+ return EINVAL;
+
+ if (!id && (m->dynpt > RTP_DYNPT_END))
+ return ERANGE;
+
+ fmt = mem_zalloc(sizeof(*fmt), destructor);
+ if (!fmt)
+ return ENOMEM;
+
+ if (prepend)
+ list_prepend(&m->lfmtl, &fmt->le, fmt);
+ else
+ list_append(&m->lfmtl, &fmt->le, fmt);
+
+ if (id)
+ err = str_dup(&fmt->id, id);
+ else
+ err = re_sdprintf(&fmt->id, "%i", m->dynpt++);
+ if (err)
+ goto out;
+
+ if (name) {
+ err = str_dup(&fmt->name, name);
+ if (err)
+ goto out;
+ }
+
+ if (params) {
+ va_list ap;
+
+ va_start(ap, params);
+ err = re_vsdprintf(&fmt->params, params, ap);
+ va_end(ap);
+
+ if (err)
+ goto out;
+ }
+
+ fmt->pt = atoi(fmt->id);
+ fmt->srate = srate;
+ fmt->ch = ch;
+ fmt->ench = ench;
+ fmt->cmph = cmph;
+ fmt->data = ref ? mem_ref(data) : data;
+ fmt->ref = ref;
+ fmt->sup = true;
+
+ out:
+ if (err)
+ mem_deref(fmt);
+ else if (fmtp)
+ *fmtp = fmt;
+
+ return err;
+}
+
+
+int sdp_format_radd(struct sdp_media *m, const struct pl *id)
+{
+ struct sdp_format *fmt;
+ int err;
+
+ if (!m || !id)
+ return EINVAL;
+
+ fmt = mem_zalloc(sizeof(*fmt), destructor);
+ if (!fmt)
+ return ENOMEM;
+
+ list_append(&m->rfmtl, &fmt->le, fmt);
+
+ err = pl_strdup(&fmt->id, id);
+ if (err)
+ goto out;
+
+ fmt->pt = atoi(fmt->id);
+
+ out:
+ if (err)
+ mem_deref(fmt);
+
+ return err;
+}
+
+
+struct sdp_format *sdp_format_find(const struct list *lst, const struct pl *id)
+{
+ struct le *le;
+
+ if (!lst || !id)
+ return NULL;
+
+ for (le=lst->head; le; le=le->next) {
+
+ struct sdp_format *fmt = le->data;
+
+ if (pl_strcmp(id, fmt->id))
+ continue;
+
+ return fmt;
+ }
+
+ return NULL;
+}
+
+
+/**
+ * Set the parameters of an SDP format
+ *
+ * @param fmt SDP Format
+ * @param params Formatted parameters
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_format_set_params(struct sdp_format *fmt, const char *params, ...)
+{
+ int err = 0;
+
+ if (!fmt)
+ return EINVAL;
+
+ fmt->params = mem_deref(fmt->params);
+
+ if (params) {
+ va_list ap;
+
+ va_start(ap, params);
+ err = re_vsdprintf(&fmt->params, params, ap);
+ va_end(ap);
+ }
+
+ return err;
+}
+
+
+/**
+ * Compare two SDP Formats
+ *
+ * @param fmt1 First SDP format
+ * @param fmt2 Second SDP format
+ *
+ * @return True if matching, False if not
+ */
+bool sdp_format_cmp(const struct sdp_format *fmt1,
+ const struct sdp_format *fmt2)
+{
+ if (!fmt1 || !fmt2)
+ return false;
+
+ if (fmt1->pt < RTP_DYNPT_START && fmt2->pt < RTP_DYNPT_START) {
+
+ if (!fmt1->id || !fmt2->id)
+ return false;
+
+ return strcmp(fmt1->id, fmt2->id) ? false : true;
+ }
+
+ if (str_casecmp(fmt1->name, fmt2->name))
+ return false;
+
+ if (fmt1->srate != fmt2->srate)
+ return false;
+
+ if (fmt1->ch != fmt2->ch)
+ return false;
+
+ if (fmt1->cmph && !fmt1->cmph(fmt1->params, fmt2->params, fmt1->data))
+ return false;
+
+ if (fmt2->cmph && !fmt2->cmph(fmt2->params, fmt1->params, fmt2->data))
+ return false;
+
+ return true;
+}
+
+
+/**
+ * Print SDP Format debug information
+ *
+ * @param pf Print function for output
+ * @param fmt SDP Format
+ *
+ * @return 0 if success, otherwise errorcode
+ */
+int sdp_format_debug(struct re_printf *pf, const struct sdp_format *fmt)
+{
+ int err;
+
+ if (!fmt)
+ return 0;
+
+ err = re_hprintf(pf, "%3s", fmt->id);
+
+ if (fmt->name)
+ err |= re_hprintf(pf, " %s/%u/%u",
+ fmt->name, fmt->srate, fmt->ch);
+
+ if (fmt->params)
+ err |= re_hprintf(pf, " (%s)", fmt->params);
+
+ if (fmt->sup)
+ err |= re_hprintf(pf, " *");
+
+ return err;
+}