mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	translate.c: Only select audio codecs to determine the best translation choice.
Given a source capability of h264 and ulaw, a destination capability of h264 and g722 then ast_translator_best_choice() would pick h264 as the best choice even though h264 is a video codec and Asterisk only supports translation of audio codecs. When the audio starts flowing, there are warnings about a codec mismatch when the channel tries to write a frame to the peer. * Made ast_translator_best_choice() only select audio codecs. * Restore a check in channel.c:set_format() lost after v1.8 to prevent trying to set a non-audio codec. This is an intermediate patch for a series of patches aimed at improving translation path choices for ASTERISK-24841. This patch is a complete enough fix for ASTERISK-21777 as the v11 version of ast_translator_best_choice() does the same thing. However, chan_sip.c still somehow tries to call ast_codec_choose() which then calls ast_best_codec() with a capability set that doesn't contain any audio formats for the incoming call. The remaining warning message seems to be a benign transient. ASTERISK-21777 #close Reported by: Nick Ruggles ASTERISK-24380 #close Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/4605/ ........ Merged revisions 434614 from http://svn.asterisk.org/svn/asterisk/branches/11 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@434615 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -1271,9 +1271,12 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap, | ||||
| { | ||||
| 	unsigned int besttablecost = INT_MAX; | ||||
| 	unsigned int beststeps = INT_MAX; | ||||
| 	struct ast_format *fmt; | ||||
| 	struct ast_format *dst; | ||||
| 	struct ast_format *src; | ||||
| 	RAII_VAR(struct ast_format *, best, NULL, ao2_cleanup); | ||||
| 	RAII_VAR(struct ast_format *, bestdst, NULL, ao2_cleanup); | ||||
| 	RAII_VAR(struct ast_format_cap *, joint_cap, NULL, ao2_cleanup); | ||||
| 	struct ast_format_cap *joint_cap; | ||||
| 	int i; | ||||
| 	int j; | ||||
|  | ||||
| @@ -1282,80 +1285,71 @@ int ast_translator_best_choice(struct ast_format_cap *dst_cap, | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (!(joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) { | ||||
| 	joint_cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT); | ||||
| 	if (!joint_cap) { | ||||
| 		return -1; | ||||
| 	} | ||||
| 	ast_format_cap_get_compatible(dst_cap, src_cap, joint_cap); | ||||
|  | ||||
| 	for (i = 0; i < ast_format_cap_count(joint_cap); ++i) { | ||||
| 		struct ast_format *fmt = | ||||
| 			ast_format_cap_get_format(joint_cap, i); | ||||
|  | ||||
| 		if (!fmt) { | ||||
| 	for (i = 0; i < ast_format_cap_count(joint_cap); ++i, ao2_cleanup(fmt)) { | ||||
| 		fmt = ast_format_cap_get_format(joint_cap, i); | ||||
| 		if (!fmt | ||||
| 			|| ast_format_get_type(fmt) != AST_MEDIA_TYPE_AUDIO) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (!best) { | ||||
| 			/* No ao2_ref operations needed, we're done with fmt */ | ||||
| 			best = fmt; | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		if (ast_format_get_sample_rate(best) < | ||||
| 		    ast_format_get_sample_rate(fmt)) { | ||||
| 		if (!best | ||||
| 			|| ast_format_get_sample_rate(best) < ast_format_get_sample_rate(fmt)) { | ||||
| 			ao2_replace(best, fmt); | ||||
| 		} | ||||
| 		ao2_ref(fmt, -1); | ||||
| 	} | ||||
| 	ao2_ref(joint_cap, -1); | ||||
|  | ||||
| 	if (best) { | ||||
| 		ao2_replace(*dst_fmt_out, best); | ||||
| 		ao2_replace(*src_fmt_out, best); | ||||
| 		return 0; | ||||
| 	} | ||||
|  | ||||
| 	/* need to translate */ | ||||
| 	AST_RWLIST_RDLOCK(&translators); | ||||
|  | ||||
| 	for (i = 0; i < ast_format_cap_count(dst_cap); ++i) { | ||||
| 		struct ast_format *dst = | ||||
| 			ast_format_cap_get_format(dst_cap, i); | ||||
|  | ||||
| 		if (!dst) { | ||||
| 	for (i = 0; i < ast_format_cap_count(dst_cap); ++i, ao2_cleanup(dst)) { | ||||
| 		dst = ast_format_cap_get_format(dst_cap, i); | ||||
| 		if (!dst | ||||
| 			|| ast_format_get_type(dst) != AST_MEDIA_TYPE_AUDIO) { | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		for (j = 0; j < ast_format_cap_count(src_cap); ++j) { | ||||
| 			struct ast_format *src = | ||||
| 				ast_format_cap_get_format(src_cap, j); | ||||
| 			int x, y; | ||||
| 		for (j = 0; j < ast_format_cap_count(src_cap); ++j, ao2_cleanup(src)) { | ||||
| 			int x; | ||||
| 			int y; | ||||
|  | ||||
| 			if (!src) { | ||||
| 			src = ast_format_cap_get_format(src_cap, j); | ||||
| 			if (!src | ||||
| 				|| ast_format_get_type(src) != AST_MEDIA_TYPE_AUDIO) { | ||||
| 				continue; | ||||
| 			} | ||||
|  | ||||
| 			x = format2index(src); | ||||
| 			y = format2index(dst); | ||||
| 			if (x < 0 || y < 0) { | ||||
| 				ao2_ref(src, -1); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) { | ||||
| 				ao2_ref(src, -1); | ||||
| 				continue; | ||||
| 			} | ||||
| 			if (((matrix_get(x, y)->table_cost < besttablecost) || | ||||
| 			     (matrix_get(x, y)->multistep < beststeps))) { | ||||
| 			if (matrix_get(x, y)->table_cost < besttablecost | ||||
| 				|| matrix_get(x, y)->multistep < beststeps) { | ||||
| 				/* better than what we have so far */ | ||||
| 				ao2_replace(best, src); | ||||
| 				ao2_replace(bestdst, dst); | ||||
| 				besttablecost = matrix_get(x, y)->table_cost; | ||||
| 				beststeps = matrix_get(x, y)->multistep; | ||||
| 			} | ||||
| 			ao2_ref(src, -1); | ||||
| 		} | ||||
| 		ao2_ref(dst, -1); | ||||
| 	} | ||||
| 	AST_RWLIST_UNLOCK(&translators); | ||||
|  | ||||
| 	if (!best) { | ||||
| 		return -1; | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user