[asterisk-commits] file: branch file/mf-attributes r417735 - in /team/file/mf-attributes: channe...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Jul 1 18:37:49 CDT 2014


Author: file
Date: Tue Jul  1 18:37:46 2014
New Revision: 417735

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417735
Log:
Add progress so far. The APIs have been changed, updated, added. chan_sip and chan_pjsip have been tweaked. Currently in progress is moving the existing res_format_attr modules over.

Modified:
    team/file/mf-attributes/channels/chan_sip.c
    team/file/mf-attributes/include/asterisk/format.h
    team/file/mf-attributes/include/asterisk/rtp_engine.h
    team/file/mf-attributes/main/format.c
    team/file/mf-attributes/main/rtp_engine.c
    team/file/mf-attributes/res/res_format_attr_celt.c
    team/file/mf-attributes/res/res_format_attr_h263.c
    team/file/mf-attributes/res/res_pjsip_sdp_rtp.c

Modified: team/file/mf-attributes/channels/chan_sip.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/channels/chan_sip.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/channels/chan_sip.c (original)
+++ team/file/mf-attributes/channels/chan_sip.c Tue Jul  1 18:37:46 2014
@@ -11286,8 +11286,12 @@
 
 		if ((format = ast_rtp_codecs_get_payload_format(newaudiortp, codec))) {
 			unsigned int bit_rate;
-
-			if (!ast_format_sdp_parse(format, fmtp_string)) {
+			struct ast_format *format_parsed;
+
+			format_parsed = ast_format_sdp_parse(format, fmtp_string);
+			if (format_parsed) {
+				ast_rtp_codecs_payload_replace_format(newaudiortp, codec, format_parsed);
+				ao2_replace(format, format_parsed);
 				found = TRUE;
 			} else {
 				ast_rtp_codecs_payloads_unset(newaudiortp, NULL, codec);
@@ -11363,7 +11367,13 @@
 		struct ast_format *format;
 
 		if ((format = ast_rtp_codecs_get_payload_format(newvideortp, codec))) {
-			if (!ast_format_sdp_parse(format, fmtp_string)) {
+			struct ast_format *format_parsed;
+
+			format_parsed = ast_format_sdp_parse(format, fmtp_string);
+
+			if (format_parsed) {
+				ast_rtp_codecs_payload_replace_format(newvideortp, codec, format_parsed);
+				ao2_replace(format, format_parsed);
 				found = TRUE;
 			} else {
 				ast_rtp_codecs_payloads_unset(newvideortp, NULL, codec);

Modified: team/file/mf-attributes/include/asterisk/format.h
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/include/asterisk/format.h?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/include/asterisk/format.h (original)
+++ team/file/mf-attributes/include/asterisk/format.h Tue Jul  1 18:37:46 2014
@@ -48,6 +48,17 @@
 	 */
 	void (*const format_destroy)(struct ast_format *format);
 
+	/**
+	 * \brief Callback for when the format is cloned, used to clone attributes
+	 *
+	 * \param src Source format of attributes
+	 * \param dst Destination format for attributes
+	 *
+	 * \retval 0 success
+	 * \retval -1 failure
+	 */
+	int (*const format_clone)(const struct ast_format *src, struct ast_format *dst);
+
 	/*!
 	 * \brief Determine if format 1 is a subset of format 2.
 	 *
@@ -80,10 +91,11 @@
 	 * \param name The name of the attribute
 	 * \param value The value of the attribute
 	 *
-	 * \retval 0 success
-	 * \retval -1 failure
-	 */
-	int (* const format_attribute_set)(struct ast_format *format, const char *name, const char *value);
+	 * \retval non-NULL success
+	 * \retval NULL failure
+	 */
+	struct ast_format *(* const format_attribute_set)(const struct ast_format *format,
+		const char *name, const char *value);
 
 	/*
 	 * \brief Parse SDP attribute information, interpret it, and store it in the format structure.
@@ -91,10 +103,10 @@
 	 * \param format Format to set attributes on
 	 * \param attributes A string containing only the attributes from the fmtp line
 	 *
-	 * \retval 0 Success, values were valid
-	 * \retval -1 Failure, some values were not acceptable
-	 */
-	int (* const format_sdp_parse)(struct ast_format *format, const char *attributes);
+	 * \retval non-NULL Success, values were valid
+	 * \retval NULL Failure, some values were not acceptable
+	 */
+	struct ast_format *(* const format_sdp_parse)(const struct ast_format *format, const char *attributes);
 
 	/*!
 	 * \brief Generate SDP attribute information from an ast_format_attr structure.
@@ -149,6 +161,19 @@
 struct ast_format *ast_format_create_named(const char *format_name, struct ast_codec *codec);
 
 /*!
+ * \brief Clone an existing media format so it can be modified
+ *
+ * \param format The existing media format
+ *
+ * \note The format is returned with reference count incremented. It must be released using
+ * ao2_ref or ao2_cleanup.
+ *
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_format *ast_format_clone(const struct ast_format *format);
+
+/*!
  * \brief Compare two formats
  *
  * \retval ast_format_cmp_res representing the result of comparing format1 and format2.
@@ -172,10 +197,11 @@
  * \param name Attribute name
  * \param value Attribute value
  *
- * \retval 0 success
- * \retval -1 failure
- */
-int ast_format_attribute_set(struct ast_format *format, const char *name, const char *value);
+ * \retval non-NULL success
+ * \retval NULL failure
+ */
+struct ast_format *ast_format_attribute_set(const struct ast_format *format, const char *name,
+	const char *value);
 
 /*!
  * \brief This function is used to have a media format aware module parse and interpret
@@ -185,10 +211,10 @@
  * \param format to set
  * \param attributes string containing the fmtp line from the SDP
  *
- * \retval 0 success, attribute values were valid
- * \retval -1 failure, values were not acceptable
- */
-int ast_format_sdp_parse(struct ast_format *format, const char *attributes);
+ * \retval non-NULL success, attribute values were valid
+ * \retval NULL failure, values were not acceptable
+ */
+struct ast_format *ast_format_sdp_parse(const struct ast_format *format, const char *attributes);
 
 /*!
  * \brief This function is used to produce an fmtp SDP line for an Asterisk format. The
@@ -224,6 +250,23 @@
 #define ast_format_interface_register(codec, interface) __ast_format_interface_register(codec, interface, ast_module_info->self)
 
 /*!
+ * \brief Get the attribute data on a format
+ *
+ * \param format The media format
+ *
+ * \return Currently set attribute data
+ */
+void *ast_format_get_attribute_data(const struct ast_format *format);
+
+/*!
+ * \brief Set the attribute data on a format
+ *
+ * \param format The media format
+ * \param attribute_data The attribute data
+ */
+void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data);
+
+/*!
  * \brief Get the name associated with a format
  *
  * \param format The media format

Modified: team/file/mf-attributes/include/asterisk/rtp_engine.h
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/include/asterisk/rtp_engine.h?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/include/asterisk/rtp_engine.h (original)
+++ team/file/mf-attributes/include/asterisk/rtp_engine.h Tue Jul  1 18:37:46 2014
@@ -1,4 +1,4 @@
-/*
+ /*
  * Asterisk -- An open source telephony toolkit.
  *
  * Copyright (C) 1999 - 2009, Digium, Inc.
@@ -1255,6 +1255,20 @@
 struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload);
 
 /*!
+ * \brief Update the format associated with a payload in a codecs structure
+ *
+ * \param codecs Codecs structure to operate on
+ * \param payload Numerical payload to look up
+ * \param format The format to replace the existing one
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ *
+ * \since 13
+ */
+int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format);
+
+/*!
  * \brief Retrieve the actual ast_format stored on the codecs structure for a specific payload
  *
  * \param codecs Codecs structure to look in

Modified: team/file/mf-attributes/main/format.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/main/format.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/main/format.c (original)
+++ team/file/mf-attributes/main/format.c Tue Jul  1 18:37:46 2014
@@ -156,6 +156,16 @@
 	return 0;
 }
 
+void *ast_format_get_attribute_data(const struct ast_format *format)
+{
+	return format->attribute_data;
+}
+
+void ast_format_set_attribute_data(struct ast_format *format, void *attribute_data)
+{
+	format->attribute_data = attribute_data;
+}
+
 /*! \brief Destructor for media formats */
 static void format_destroy(void *obj)
 {
@@ -188,6 +198,22 @@
 	}
 
 	return format;
+}
+
+struct ast_format *ast_format_clone(const struct ast_format *format)
+{
+	struct ast_format *cloned = ast_format_create_named(format->name, format->codec);
+
+	if (!cloned) {
+		return NULL;
+	}
+
+	if (format->interface && format->interface->format_clone(format, cloned)) {
+		ao2_ref(cloned, -1);
+		return NULL;
+	}
+
+	return cloned;
 }
 
 struct ast_format *ast_format_create(struct ast_codec *codec)
@@ -234,19 +260,19 @@
 	return format1->interface->format_get_joint(format1, format2);
 }
 
-int ast_format_attribute_set(struct ast_format *format, const char *name, const char *value)
+struct ast_format *ast_format_attribute_set(const struct ast_format *format, const char *name, const char *value)
 {
 	if (!format->interface || !format->interface->format_attribute_set) {
-		return -1;
+		return NULL;
 	}
 
 	return format->interface->format_attribute_set(format, name, value);
 }
 
-int ast_format_sdp_parse(struct ast_format *format, const char *attributes)
+struct ast_format *ast_format_sdp_parse(const struct ast_format *format, const char *attributes)
 {
 	if (!format->interface || !format->interface->format_sdp_parse) {
-		return -1;
+		return NULL;
 	}
 
 	return format->interface->format_sdp_parse(format, attributes);

Modified: team/file/mf-attributes/main/rtp_engine.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/main/rtp_engine.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/main/rtp_engine.c (original)
+++ team/file/mf-attributes/main/rtp_engine.c Tue Jul  1 18:37:46 2014
@@ -809,6 +809,24 @@
 	return result;
 }
 
+int ast_rtp_codecs_payload_replace_format(struct ast_rtp_codecs *codecs, int payload, struct ast_format *format)
+{
+	struct ast_rtp_payload_type *type;
+
+	if (payload < 0 || payload >= AST_RTP_MAX_PT) {
+		return -1;
+	}
+
+	type = ao2_find(codecs->payloads, &payload, OBJ_KEY | OBJ_NOLOCK);
+	if (!type) {
+		return -1;
+	}
+
+	ao2_replace(type->format, format);
+	ao2_ref(type, -1);
+
+	return 0;
+}
 
 struct ast_format *ast_rtp_codecs_get_payload_format(struct ast_rtp_codecs *codecs, int payload)
 {

Modified: team/file/mf-attributes/res/res_format_attr_celt.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/res/res_format_attr_celt.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/res/res_format_attr_celt.c (original)
+++ team/file/mf-attributes/res/res_format_attr_celt.c Tue Jul  1 18:37:46 2014
@@ -45,152 +45,159 @@
 	unsigned int framesize;
 };
 
-static int celt_sdp_parse(struct ast_format_attr *format_attr, const char *attributes)
-{
-	struct celt_attr *attr = (struct celt_attr *) format_attr;
+static void celt_destroy(struct ast_format *format)
+{
+	struct celt_attr *attr = ast_format_get_attribute_data(format);
+
+	ast_free(attr);
+}
+
+static int celt_clone(const struct ast_format *src, struct ast_format *dst)
+{
+	struct celt_attr *original = ast_format_get_attribute_data(src);
+	struct celt_attr *attr = ast_calloc(1, sizeof(*attr));
+
+	if (!attr) {
+		return -1;
+	}
+
+	if (original) {
+		*attr = *original;
+	}
+
+	ast_format_set_attribute_data(dst, attr);
+
+	return 0;
+}
+
+static struct ast_format *celt_sdp_parse(const struct ast_format *format, const char *attributes)
+{
+	struct ast_format *cloned;
+	struct celt_attr *attr;
 	unsigned int val;
+
+	cloned = ast_format_clone(format);
+	if (!cloned) {
+		return NULL;
+	}
+	attr = ast_format_get_attribute_data(cloned);
 
 	if (sscanf(attributes, "framesize=%30u", &val) == 1) {
 		attr->framesize = val;
 	}
 
-	return 0;
-}
-
-static void celt_sdp_generate(const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str)
-{
-	struct celt_attr *attr = (struct celt_attr *) format_attr;
-
-	if (!attr->framesize) {
+	return cloned;
+}
+
+static void celt_sdp_generate(const struct ast_format *format, unsigned int payload, struct ast_str **str)
+{
+	struct celt_attr *attr = ast_format_get_attribute_data(format);
+
+	if (!attr || !attr->framesize) {
 		return;
 	}
 
-	ast_str_append(str, 0, "a=fmtp:%u framesize=%u\r\n", payload, attr->framesize);
-}
-
-static enum ast_format_cmp_res celt_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
-{
-	struct celt_attr *attr1 = (struct celt_attr *) fattr1;
-	struct celt_attr *attr2 = (struct celt_attr *) fattr2;
-
-	if (attr1->samplerate == attr2->samplerate) {
+	ast_str_append(str, 0, "a=fmtp:%d framesize=%d\r\n", payload, attr->framesize);
+}
+
+static enum ast_format_cmp_res celt_cmp(const struct ast_format *format1, const struct ast_format *format2)
+{
+	struct celt_attr *attr1 = ast_format_get_attribute_data(format1);
+	struct celt_attr *attr2 = ast_format_get_attribute_data(format2);
+
+	if (((!attr1 || !attr1->samplerate) && (!attr2 || !attr2->samplerate)) ||
+		(attr1->samplerate == attr2->samplerate)) {
 		return AST_FORMAT_CMP_EQUAL;
 	}
+
 	return AST_FORMAT_CMP_NOT_EQUAL;
 }
 
-static int celt_get_val(const struct ast_format_attr *fattr, int key, void *result)
-{
-	const struct celt_attr *attr = (struct celt_attr *) fattr;
-	int *val = result;
-
-	switch (key) {
-	case CELT_ATTR_KEY_SAMP_RATE:
-		*val = attr->samplerate;
-		break;
-	case CELT_ATTR_KEY_MAX_BITRATE:
-		*val = attr->maxbitrate;
-		break;
-	case CELT_ATTR_KEY_FRAME_SIZE:
-		*val = attr->framesize;
-		break;
-	default:
-		ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
-		return -1;
-	}
-	return 0;
-}
-
-static int celt_isset(const struct ast_format_attr *fattr, va_list ap)
-{
-	enum celt_attr_keys key;
-	const struct celt_attr *attr = (struct celt_attr *) fattr;
-
-	for (key = va_arg(ap, int);
-		key != AST_FORMAT_ATTR_END;
-		key = va_arg(ap, int))
-	{
-		switch (key) {
-		case CELT_ATTR_KEY_SAMP_RATE:
-			if (attr->samplerate != (va_arg(ap, int))) {
-				return -1;
-			}
-			break;
-		case CELT_ATTR_KEY_MAX_BITRATE:
-			if (attr->maxbitrate != (va_arg(ap, int))) {
-				return -1;
-			}
-			break;
-		case CELT_ATTR_KEY_FRAME_SIZE:
-			if (attr->framesize != (va_arg(ap, int))) {
-				return -1;
-			}
-			break;
-		default:
-			ast_log(LOG_WARNING, "unknown attribute type %u\n", key);
-			return -1;
+static struct ast_format *celt_getjoint(const struct ast_format *format1, const struct ast_format *format2)
+{
+	struct celt_attr *attr1 = ast_format_get_attribute_data(format1);
+	struct celt_attr *attr2 = ast_format_get_attribute_data(format2);
+	struct ast_format *jointformat;
+	struct celt_attr *jointattr;
+
+	if (attr1 && attr2 && (attr1->samplerate != attr2->samplerate)) {
+		return NULL;
+	}
+
+	jointformat = ast_format_clone(format1);
+	if (!jointformat) {
+		return NULL;
+	}
+	jointattr = ast_format_get_attribute_data(jointformat);
+
+	/* either would work, they are guaranteed the same at this point. */
+	jointattr->samplerate = attr1->samplerate;
+	/* Take the lowest max bitrate */
+	jointattr->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
+
+	jointattr->framesize = attr2->framesize; /* TODO figure out what joint framesize means */
+
+	return jointformat;
+}
+
+static struct ast_format *celt_set(const struct ast_format *format, const char *name, const char *value)
+{
+	struct ast_format *cloned;
+	struct celt_attr *attr;
+	unsigned int val;
+
+	cloned = ast_format_clone(format);
+	if (!cloned) {
+		return NULL;
+	}
+	attr = ast_format_get_attribute_data(cloned);
+
+	if (!strcasecmp(name, "sample_rate")) {
+		if (sscanf(value, "%30u", &val) != 1) {
+			ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
+				value, name);
+			ao2_ref(cloned, -1);
+			return NULL;
 		}
-	}
-	return 0;
-}
-static int celt_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
-{
-	struct celt_attr *attr1 = (struct celt_attr *) fattr1;
-	struct celt_attr *attr2 = (struct celt_attr *) fattr2;
-	struct celt_attr *attr_res = (struct celt_attr *) result;
-
-	/* sample rate is the only attribute that has any bearing on if joint capabilities exist or not */
-	if (attr1->samplerate != attr2->samplerate) {
-		return -1;
-	}
-	/* either would work, they are guaranteed the same at this point. */
-	attr_res->samplerate = attr1->samplerate;
-	/* Take the lowest max bitrate */
-	attr_res->maxbitrate = MIN(attr1->maxbitrate, attr2->maxbitrate);
-
-	attr_res->framesize = attr2->framesize; /* TODO figure out what joint framesize means */
-	return 0;
-}
-
-static void celt_set(struct ast_format_attr *fattr, va_list ap)
-{
-	enum celt_attr_keys key;
-	struct celt_attr *attr = (struct celt_attr *) fattr;
-
-	for (key = va_arg(ap, int);
-		key != AST_FORMAT_ATTR_END;
-		key = va_arg(ap, int))
-	{
-		switch (key) {
-		case CELT_ATTR_KEY_SAMP_RATE:
-			attr->samplerate = (va_arg(ap, int));
-			break;
-		case CELT_ATTR_KEY_MAX_BITRATE:
-			attr->maxbitrate = (va_arg(ap, int));
-			break;
-		case CELT_ATTR_KEY_FRAME_SIZE:
-			attr->framesize = (va_arg(ap, int));
-			break;
-		default:
-			ast_log(LOG_WARNING, "unknown attribute type %u\n", key);
+		attr->samplerate = val;
+	} else if (!strcasecmp(name, "max_bitrate")) {
+		if (sscanf(value, "%30u", &val) != 1) {
+			ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
+				value, name);
+			ao2_ref(cloned, -1);
+			return NULL;
 		}
-	}
-}
-
-static struct ast_format_attr_interface celt_interface = {
-	.id = AST_FORMAT_CELT,
-	.format_attr_cmp = celt_cmp,
-	.format_attr_get_joint = celt_getjoint,
-	.format_attr_set = celt_set,
-	.format_attr_isset = celt_isset,
-	.format_attr_get_val = celt_get_val,
-	.format_attr_sdp_parse = celt_sdp_parse,
-	.format_attr_sdp_generate = celt_sdp_generate,
+		attr->maxbitrate = val;
+	} else if (!strcasecmp(name, "frame_size")) {
+		if (sscanf(value, "%30u", &val) != 1) {
+			ast_log(LOG_WARNING, "Unknown value '%s' for attribute type '%s'\n",
+				value, name);
+			ao2_ref(cloned, -1);
+			return NULL;
+		}
+		attr->framesize = val;
+	} else {
+		ast_log(LOG_WARNING, "Unknown attribute type '%s'\n", name);
+		ao2_ref(cloned, -1);
+		return NULL;
+	}
+
+	return cloned;
+}
+
+static struct ast_format_interface celt_interface = {
+	.format_destroy = celt_destroy,
+	.format_clone = celt_clone,
+	.format_cmp = celt_cmp,
+	.format_get_joint = celt_getjoint,
+	.format_attribute_set = celt_set,
+	.format_sdp_parse = celt_sdp_parse,
+	.format_sdp_generate = celt_sdp_generate,
 };
 
 static int load_module(void)
 {
-	if (ast_format_attr_reg_interface(&celt_interface)) {
+	if (ast_format_interface_register("celt", &celt_interface)) {
 		return AST_MODULE_LOAD_DECLINE;
 	}
 
@@ -199,7 +206,6 @@
 
 static int unload_module(void)
 {
-	ast_format_attr_unreg_interface(&celt_interface);
 	return 0;
 }
 

Modified: team/file/mf-attributes/res/res_format_attr_h263.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/res/res_format_attr_h263.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/res/res_format_attr_h263.c (original)
+++ team/file/mf-attributes/res/res_format_attr_h263.c Tue Jul  1 18:37:46 2014
@@ -38,32 +38,56 @@
 #include "asterisk/module.h"
 #include "asterisk/format.h"
 
-enum h263_attr_keys {
-	H263_ATTR_KEY_SQCIF,       /*!< Minimum picture interval for SQCIF resolution */
-	H263_ATTR_KEY_QCIF,        /*!< Minimum picture interval for QCIF resolution */
-	H263_ATTR_KEY_CIF,         /*!< Minimum picture interval for CIF resolution */
-	H263_ATTR_KEY_CIF4,        /*!< Minimum picture interval for CIF4 resolution */
-	H263_ATTR_KEY_CIF16,       /*!< Minimum picture interval for CIF16 resolution */
-	H263_ATTR_KEY_VGA,         /*!< Minimum picture interval for VGA resolution */
-	H263_ATTR_KEY_CUSTOM_XMAX, /*!< Custom resolution (Xmax) */
-	H263_ATTR_KEY_CUSTOM_YMAX, /*!< Custom resolution (Ymax) */
-	H263_ATTR_KEY_CUSTOM_MPI,  /*!< Custom resolution (MPI) */
-	H263_ATTR_KEY_F,           /*!< F annex support */
-	H263_ATTR_KEY_I,           /*!< I annex support */
-	H263_ATTR_KEY_J,           /*!< J annex support */
-	H263_ATTR_KEY_T,           /*!< T annex support */
-	H263_ATTR_KEY_K,           /*!< K annex support */
-	H263_ATTR_KEY_N,           /*!< N annex support */
-	H263_ATTR_KEY_P_SUB1,      /*!< Reference picture resampling (sub mode 1) */
-	H263_ATTR_KEY_P_SUB2,      /*!< Reference picture resampling (sub mode 2) */
-	H263_ATTR_KEY_P_SUB3,      /*!< Reference picture resampling (sub mode 3) */
-	H263_ATTR_KEY_P_SUB4,      /*!< Reference picture resampling (sub mode 4) */
-	H263_ATTR_KEY_PAR_WIDTH,   /*!< Pixel aspect ratio (width) */
-	H263_ATTR_KEY_PAR_HEIGHT,  /*!< Pixel aspect ratio (height) */
-	H263_ATTR_KEY_BPP,         /*!< Bits per picture maximum */
-	H263_ATTR_KEY_HRD,         /*!< Hypothetical reference decoder status */
-	H263_ATTR_KEY_END,         /*!< End terminator for list */
+struct h263_attr {
+	unsigned int SQCIF;       /*!< Minimum picture interval for SQCIF resolution */
+	unsigned int QCIF;        /*!< Minimum picture interval for QCIF resolution */
+	unsigned int CIF;         /*!< Minimum picture interval for CIF resolution */
+	unsigned int CIF4;        /*!< Minimum picture interval for CIF4 resolution */
+	unsigned int CIF16;       /*!< Minimum picture interval for CIF16 resolution */
+	unsigned int VGA;         /*!< Minimum picture interval for VGA resolution */
+	unsigned int CUSTOM_XMAX; /*!< Custom resolution (Xmax) */
+	unsigned int CUSTOM_YMAX; /*!< Custom resolution (Ymax) */
+	unsigned int CUSTOM_MPI;  /*!< Custom resolution (MPI) */
+	unsigned int F;           /*!< F annex support */
+	unsigned int I;           /*!< I annex support */
+	unsigned int J;           /*!< J annex support */
+	unsigned int T;           /*!< T annex support */
+	unsigned int K;           /*!< K annex support */
+	unsigned int N;           /*!< N annex support */
+	unsigned int P_SUB1;      /*!< Reference picture resampling (sub mode 1) */
+	unsigned int P_SUB2;      /*!< Reference picture resampling (sub mode 2) */
+	unsigned int P_SUB3;      /*!< Reference picture resampling (sub mode 3) */
+	unsigned int P_SUB4;      /*!< Reference picture resampling (sub mode 4) */
+	unsigned int PAR_WIDTH;   /*!< Pixel aspect ratio (width) */
+	unsigned int PAR_HEIGHT;  /*!< Pixel aspect ratio (height) */
+	unsigned int BPP;         /*!< Bits per picture maximum */
+	unsigned int HRD;         /*!< Hypothetical reference decoder status */
 };
+
+static void h263_destroy(struct ast_format *format)
+{
+	struct h263_attr *attr = ast_format_get_attribute_data(format);
+
+	ast_free(attr);
+}
+
+static int h263_clone(const struct ast_format *src, struct ast_format *dst)
+{
+	struct h263_attr *original = ast_format_get_attribute_data(src);
+	struct h263_attr *attr = ast_calloc(1, sizeof(*attr));
+
+	if (!attr) {
+		return -1;
+	}
+
+	if (original) {
+		*attr = *original;
+	}
+
+	ast_format_set_attribute_data(dst, attr);
+
+	return 0;
+}
 
 static int h263_format_attr_get_joint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
 {
@@ -77,106 +101,66 @@
 	return 0;
 }
 
-static int h263_format_attr_sdp_parse(struct ast_format_attr *format_attr, const char *attributes)
+static struct ast_format *h263_sdp_parse(const struct ast_format *format, const char *attributes)
 {
 	char *attribs = ast_strdupa(attributes), *attrib;
+	struct ast_format *cloned;
+	struct celt_attr *attr;
+	unsigned int val;
+
+	cloned = ast_format_clone(format);
+	if (!cloned) {
+		return NULL;
+	}
+	attr = ast_format_get_attribute_data(cloned);
 
 	while ((attrib = strsep(&attribs, ";"))) {
 		unsigned int val, val2 = 0, val3 = 0, val4 = 0;
 
 		if (sscanf(attrib, "SQCIF=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_SQCIF] = val;
+			attr->SQCIF = val;
 		} else if (sscanf(attrib, "QCIF=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_QCIF] = val;
+			attr->QCIF = val;
 		} else if (sscanf(attrib, "CIF=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_CIF] = val;
+			attr->CIF = val;
 		} else if (sscanf(attrib, "CIF4=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_CIF4] = val;
+			attr->CIF4 = val;
 		} else if (sscanf(attrib, "CIF16=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_CIF16] = val;
+			attr->CIF16 = val;
 		} else if (sscanf(attrib, "VGA=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_VGA] = val;
+			attr->VGA = val;
 		} else if (sscanf(attrib, "CUSTOM=%30u,%30u,%30u", &val, &val2, &val3) == 3) {
-			format_attr->format_attr[H263_ATTR_KEY_CUSTOM_XMAX] = val;
-			format_attr->format_attr[H263_ATTR_KEY_CUSTOM_YMAX] = val2;
-			format_attr->format_attr[H263_ATTR_KEY_CUSTOM_MPI] = val3;
+			attr->CUSTOM_XMAX = val;
+			attr->CUSTOM_YMAX = val2;
+			attr->CUSTOM_MPI = val3;
 		} else if (sscanf(attrib, "F=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_F] = val;
+			attr->F = val;
 		} else if (sscanf(attrib, "I=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_I] = val;
+			attr->I = val;
 		} else if (sscanf(attrib, "J=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_J] = val;
+			attr->J = val;
 		} else if (sscanf(attrib, "T=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_T] = val;
+			attr->T = val;
 		} else if (sscanf(attrib, "K=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_K] = val;
+			attr->K = val;
 		} else if (sscanf(attrib, "N=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_N] = val;
+			attr->N = val;
 		} else if (sscanf(attrib, "PAR=%30u:%30u", &val, &val2) == 2) {
-			format_attr->format_attr[H263_ATTR_KEY_PAR_WIDTH] = val;
-			format_attr->format_attr[H263_ATTR_KEY_PAR_HEIGHT] = val2;
+			attr->PAR_WIDTH = val;
+			attr->PAR_HEIGHT = val2;
 		} else if (sscanf(attrib, "BPP=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_BPP] = val;
+			attr->BPP = val;
 		} else if (sscanf(attrib, "HRD=%30u", &val) == 1) {
-			format_attr->format_attr[H263_ATTR_KEY_HRD] = val;
+			attr->HRD = val;
 		} else if (sscanf(attrib, "P=%30u,%30u,%30u,%30u", &val, &val2, &val3, &val4) > 0) {
-			format_attr->format_attr[H263_ATTR_KEY_P_SUB1] = val;
-			format_attr->format_attr[H263_ATTR_KEY_P_SUB2] = val2;
-			format_attr->format_attr[H263_ATTR_KEY_P_SUB3] = val3;
-			format_attr->format_attr[H263_ATTR_KEY_P_SUB4] = val4;
+			attr->P_SUB1 = val;
+			attr->P_SUB2 = val2;
+			attr->P_SUB3 = val3;
+			attr->P_SUB4 = val4;
 		}
 	}
 
-	return 0;
-}
-
-/*! \brief Helper function which converts a key enum into a string value for SDP */
-static const char *h263_attr_key_to_str(enum h263_attr_keys key, const struct ast_format_attr *format_attr)
-{
-	switch (key) {
-	case H263_ATTR_KEY_SQCIF:
-		return format_attr->format_attr[key] ? "SQCIF" : NULL;
-	case H263_ATTR_KEY_QCIF:
-		return format_attr->format_attr[key] ? "QCIF" : NULL;
-	case H263_ATTR_KEY_CIF:
-		return format_attr->format_attr[key] ? "CIF" : NULL;
-	case H263_ATTR_KEY_CIF4:
-		return format_attr->format_attr[key] ? "CIF4" : NULL;
-	case H263_ATTR_KEY_CIF16:
-		return format_attr->format_attr[key] ? "CIF16" : NULL;
-	case H263_ATTR_KEY_VGA:
-		return format_attr->format_attr[key] ? "VGA" : NULL;
-	case H263_ATTR_KEY_F:
-		return "F";
-	case H263_ATTR_KEY_I:
-		return "I";
-	case H263_ATTR_KEY_J:
-		return "J";
-	case H263_ATTR_KEY_T:
-		return "T";
-	case H263_ATTR_KEY_K:
-		return "K";
-	case H263_ATTR_KEY_N:
-		return "N";
-	case H263_ATTR_KEY_BPP:
-		return "BPP";
-	case H263_ATTR_KEY_HRD:
-		return "HRD";
-	case H263_ATTR_KEY_CUSTOM_XMAX:
-	case H263_ATTR_KEY_CUSTOM_YMAX:
-	case H263_ATTR_KEY_CUSTOM_MPI:
-	case H263_ATTR_KEY_P_SUB1:
-	case H263_ATTR_KEY_P_SUB2:
-	case H263_ATTR_KEY_P_SUB3:
-	case H263_ATTR_KEY_P_SUB4:
-	case H263_ATTR_KEY_PAR_WIDTH:
-	case H263_ATTR_KEY_PAR_HEIGHT:
-	case H263_ATTR_KEY_END:
-	default:
-		return NULL;
-	}
-
-	return NULL;
+	return cloned;
 }
 
 static void h263_format_attr_sdp_generate(const struct ast_format_attr *format_attr, unsigned int payload, struct ast_str **str)
@@ -260,10 +244,10 @@
 };
 
 static struct ast_format_attr_interface h263p_format_attr_interface = {
-        .id = AST_FORMAT_H263_PLUS,
+    .id = AST_FORMAT_H263_PLUS,
 	.format_attr_get_joint = h263_format_attr_get_joint,
-        .format_attr_sdp_parse = h263_format_attr_sdp_parse,
-        .format_attr_sdp_generate = h263_format_attr_sdp_generate,
+    .format_attr_sdp_parse = h263_format_attr_sdp_parse,
+    .format_attr_sdp_generate = h263_format_attr_sdp_generate,
 };
 
 static int unload_module(void)

Modified: team/file/mf-attributes/res/res_pjsip_sdp_rtp.c
URL: http://svnview.digium.com/svn/asterisk/team/file/mf-attributes/res/res_pjsip_sdp_rtp.c?view=diff&rev=417735&r1=417734&r2=417735
==============================================================================
--- team/file/mf-attributes/res/res_pjsip_sdp_rtp.c (original)
+++ team/file/mf-attributes/res/res_pjsip_sdp_rtp.c Tue Jul  1 18:37:46 2014
@@ -191,8 +191,16 @@
 		if ((pjmedia_sdp_attr_get_fmtp(attr, &fmtp)) == PJ_SUCCESS) {
 			sscanf(pj_strbuf(&fmtp.fmt), "%d", &num);
 			if ((format = ast_rtp_codecs_get_payload_format(codecs, num))) {
+				struct ast_format *format_parsed;
+
 				ast_copy_pj_str(fmt_param, &fmtp.fmt_param, sizeof(fmt_param));
-				ast_format_sdp_parse(format, fmt_param);
+
+				format_parsed = ast_format_sdp_parse(format, fmt_param);
+				if (format_parsed) {
+					ast_rtp_codecs_payload_replace_format(codecs, num, format_parsed);
+					ao2_ref(format_parsed, -1);
+				}
+
 				ao2_ref(format, -1);
 			}
 		}




More information about the asterisk-commits mailing list