[svn-commits] file: branch file/mf-attributes r417751 - /team/file/mf-attributes/main/format.c

SVN commits to the Digium repositories svn-commits at lists.digium.com
Wed Jul 2 06:05:19 CDT 2014


Author: file
Date: Wed Jul  2 06:05:17 2014
New Revision: 417751

URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=417751
Log:
This change does a few things:

1. Fixed a locking issue when registering a format interface
2. Links the correct object into the interfaces container
3. Removes the assumption that two formats of the same codec will have the same interface
4. Allows interfaces to be registered after other formats have been created of the same codec

This is possible because SDP parsing and attribute setting now generates a new format, which
can contain the interface even if the fed-in format did not.

Modified:
    team/file/mf-attributes/main/format.c

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=417751&r1=417750&r2=417751
==============================================================================
--- team/file/mf-attributes/main/format.c (original)
+++ team/file/mf-attributes/main/format.c Wed Jul  2 06:05:17 2014
@@ -135,7 +135,7 @@
 	SCOPED_AO2WRLOCK(lock, interfaces);
 	struct format_interface *format_interface;
 
-	format_interface = ao2_find(interfaces, codec, OBJ_SEARCH_KEY);
+	format_interface = ao2_find(interfaces, codec, OBJ_SEARCH_KEY | OBJ_NOLOCK);
 	if (format_interface) {
 		ast_log(LOG_ERROR, "A format interface is already present for codec '%s'\n", codec);
 		ao2_ref(format_interface, -1);
@@ -148,7 +148,7 @@
 	}
 
 	format_interface->interface = interface;
-	ao2_link_flags(interfaces, interface, OBJ_NOLOCK);
+	ao2_link_flags(interfaces, format_interface, OBJ_NOLOCK);
 	ao2_ref(format_interface, -1);
 
 	ast_verb(2, "Registered format interface for codec '%s'\n", codec);
@@ -223,6 +223,8 @@
 
 enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
 {
+	struct ast_format_interface *interface;
+
 	if (format1 == NULL || format2 == NULL) {
 		return AST_FORMAT_CMP_NOT_EQUAL;
 	}
@@ -235,8 +237,10 @@
 		return AST_FORMAT_CMP_NOT_EQUAL;
 	}
 
-	if (format1->interface) {
-		return format1->interface->format_cmp(format1, format2);
+	interface = format1->interface ? format1->interface : format2->interface;
+
+	if (interface) {
+		return interface->format_cmp(format1, format2);
 	}
 
 	return AST_FORMAT_CMP_EQUAL;
@@ -244,6 +248,8 @@
 
 struct ast_format *ast_format_joint(const struct ast_format *format1, const struct ast_format *format2)
 {
+	struct ast_format_interface *interface;
+
 	if (format1->codec != format2->codec) {
 		return NULL;
 	}
@@ -256,26 +262,52 @@
 		return ao2_bump((struct ast_format*)format1);
 	}
 
+	interface = format1->interface ? format1->interface : format2->interface;
+
 	/* If there is attribute data on either there has to be an interface */
-	return format1->interface->format_get_joint(format1, format2);
+	return interface->format_get_joint(format1, format2);
 }
 
 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 NULL;
-	}
-
-	return format->interface->format_attribute_set(format, name, value);
+	RAII_VAR(struct ast_format_interface *, interface, format->interface, ao2_cleanup);
+
+	if (!interface) {
+		struct format_interface *format_interface = ao2_find(interfaces, format->codec->name, OBJ_SEARCH_KEY);
+		if (format_interface) {
+			interface = ao2_bump(format_interface->interface);
+			ao2_ref(format_interface, -1);
+		}
+	} else {
+		ao2_ref(interface, +1);
+	}
+
+	if (!interface->format_attribute_set) {
+		return NULL;
+	}
+
+	return interface->format_attribute_set(format, name, value);
 }
 
 struct ast_format *ast_format_sdp_parse(const struct ast_format *format, const char *attributes)
 {
-	if (!format->interface || !format->interface->format_sdp_parse) {
-		return NULL;
-	}
-
-	return format->interface->format_sdp_parse(format, attributes);
+	RAII_VAR(struct ast_format_interface *, interface, format->interface, ao2_cleanup);
+
+	if (!interface) {
+		struct format_interface *format_interface = ao2_find(interfaces, format->codec->name, OBJ_SEARCH_KEY);
+		if (format_interface) {
+			interface = ao2_bump(format_interface->interface);
+			ao2_ref(format_interface, -1);
+		}
+	} else {
+		ao2_ref(interface, +1);
+	}
+
+	if (!interface->format_sdp_parse) {
+		return NULL;
+	}
+
+	return interface->format_sdp_parse(format, attributes);
 }
 
 void ast_format_sdp_generate(const struct ast_format *format, unsigned int payload, struct ast_str **str)




More information about the svn-commits mailing list