[asterisk-commits] tilghman: branch group/codec_bits r112873 - in /team/group/codec_bits: channe...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Fri Apr 4 16:57:05 CDT 2008


Author: tilghman
Date: Fri Apr  4 16:57:05 2008
New Revision: 112873

URL: http://svn.digium.com/view/asterisk?view=rev&rev=112873
Log:
Final commit for the afternoon

Modified:
    team/group/codec_bits/channels/chan_mgcp.c
    team/group/codec_bits/channels/chan_sip.c
    team/group/codec_bits/channels/chan_unistim.c
    team/group/codec_bits/include/asterisk/rtp.h
    team/group/codec_bits/main/rtp.c

Modified: team/group/codec_bits/channels/chan_mgcp.c
URL: http://svn.digium.com/view/asterisk/team/group/codec_bits/channels/chan_mgcp.c?view=diff&rev=112873&r1=112872&r2=112873
==============================================================================
--- team/group/codec_bits/channels/chan_mgcp.c (original)
+++ team/group/codec_bits/channels/chan_mgcp.c Fri Apr  4 16:57:05 2008
@@ -2129,7 +2129,7 @@
 				if (mgcpdebug) {
 					ast_verbose("Answering with capability %d\n", x);
 				}
-				codec = ast_rtp_lookup_codec(sub->rtp, 1, audiocodec);
+				codec = ast_rtp_lookup_codec(sub->rtp, audiocodec);
 				if (codec > -1) {
 					snprintf(costr, sizeof(costr), " %d", codec);
 					strncat(m, costr, sizeof(m) - strlen(m) - 1);
@@ -2144,7 +2144,7 @@
 			if (mgcpdebug) {
 				ast_verbose("Answering with non-codec capability %d\n", x);
 			}
-			codec = ast_rtp_lookup_code(sub->rtp, 0, x);
+			codec = ast_rtp_lookup_code(sub->rtp, x);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);

Modified: team/group/codec_bits/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/group/codec_bits/channels/chan_sip.c?view=diff&rev=112873&r1=112872&r2=112873
==============================================================================
--- team/group/codec_bits/channels/chan_sip.c (original)
+++ team/group/codec_bits/channels/chan_sip.c Fri Apr  4 16:57:05 2008
@@ -6877,9 +6877,9 @@
 			    ast_getformatname_multiple(s5, SIPBUFSIZE, newjointcapability));
 
 		ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
-			    ast_rtp_lookup_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0, 0));
+			    ast_rtp_lookup_noncodec_mime_multiple(s1, SIPBUFSIZE, p->noncodeccapability, 0),
+			    ast_rtp_lookup_noncodec_mime_multiple(s2, SIPBUFSIZE, peernoncodeccapability, 0),
+			    ast_rtp_lookup_noncodec_mime_multiple(s3, SIPBUFSIZE, newnoncodeccapability, 0));
 	}
 	if (FMT_NOT(newjointcapability)) {
 		/* If T.38 was not negotiated either, totally bail out... */
@@ -7737,7 +7737,7 @@
 
 	if (debug)
 		ast_verbose("Adding codec '%s' to SDP\n", ast_getformatname(codec));
-	if ((rtp_code = ast_rtp_lookup_codec(p->rtp, 1, codec)) == -1)
+	if ((rtp_code = ast_rtp_lookup_codec(p->rtp, codec)) == -1)
 		return;
 
 	if (p->rtp) {
@@ -7783,7 +7783,7 @@
 	if (debug)
 		ast_verbose("Adding video codec '%s' to SDP\n", ast_getformatname(codec));
 
-	if ((rtp_code = ast_rtp_lookup_codec(p->vrtp, 1, codec)) == -1)
+	if ((rtp_code = ast_rtp_lookup_codec(p->vrtp, codec)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
@@ -7805,7 +7805,7 @@
 	if (debug)
 		ast_verbose("Adding text codec '%s' to SDP\n", ast_getformatname(codec));
 
-	if ((rtp_code = ast_rtp_lookup_codec(p->trtp, 1, codec)) == -1)
+	if ((rtp_code = ast_rtp_lookup_codec(p->trtp, codec)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
@@ -7936,7 +7936,7 @@
 
 	if (debug)
 		ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_noncodec_mime_subtype(format, 0));
-	if ((rtp_code = ast_rtp_lookup_code(p->rtp, 0, format)) == -1)
+	if ((rtp_code = ast_rtp_lookup_code(p->rtp, format)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);

Modified: team/group/codec_bits/channels/chan_unistim.c
URL: http://svn.digium.com/view/asterisk/team/group/codec_bits/channels/chan_unistim.c?view=diff&rev=112873&r1=112872&r2=112873
==============================================================================
--- team/group/codec_bits/channels/chan_unistim.c (original)
+++ team/group/codec_bits/channels/chan_unistim.c Fri Apr  4 16:57:05 2008
@@ -2085,7 +2085,7 @@
 		sub->owner->readformat = fmt;
 		sub->owner->writeformat = fmt;
 	}
-	codec = ast_rtp_lookup_codec(sub->rtp, 1, sub->owner->readformat);
+	codec = ast_rtp_lookup_codec(sub->rtp, sub->owner->readformat);
 	/* Setting up RTP of the phone */
 	if (public_ip.sin_family == 0)  /* NAT IP override ?   */
 		memcpy(&public, &us, sizeof(public));   /* No defined, using IP from recvmsg  */

Modified: team/group/codec_bits/include/asterisk/rtp.h
URL: http://svn.digium.com/view/asterisk/team/group/codec_bits/include/asterisk/rtp.h?view=diff&rev=112873&r1=112872&r2=112873
==============================================================================
--- team/group/codec_bits/include/asterisk/rtp.h (original)
+++ team/group/codec_bits/include/asterisk/rtp.h Fri Apr  4 16:57:05 2008
@@ -193,8 +193,8 @@
 
 /*! \brief  Mapping between RTP payload format codes and Asterisk codes: */
 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt);
-int ast_rtp_lookup_codec(struct ast_rtp* rtp, int isAstFormat, struct ast_extended_codec code);
-int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code);
+int ast_rtp_lookup_codec(struct ast_rtp* rtp, struct ast_extended_codec code);
+int ast_rtp_lookup_code(struct ast_rtp* rtp, int code);
 
 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
 			     struct ast_extended_codec* astFormats, int* nonAstFormats);
@@ -204,8 +204,8 @@
 const char *ast_rtp_lookup_noncodec_mime_subtype(int code, enum ast_rtp_options options);
 
 /*! \brief Build a string of MIME subtype names from a capability list */
-char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
-				   const int isAstFormat, enum ast_rtp_options options);
+char *ast_rtp_lookup_noncodec_mime_multiple(char *buf, size_t size, const int capability, enum ast_rtp_options options);
+char *ast_rtp_lookup_codec_mime_multiple(char *buf, size_t size, const struct ast_extended_codec capability, enum ast_rtp_options options);
 
 void ast_rtp_setnat(struct ast_rtp *rtp, int nat);
 

Modified: team/group/codec_bits/main/rtp.c
URL: http://svn.digium.com/view/asterisk/team/group/codec_bits/main/rtp.c?view=diff&rev=112873&r1=112872&r2=112873
==============================================================================
--- team/group/codec_bits/main/rtp.c (original)
+++ team/group/codec_bits/main/rtp.c Fri Apr  4 16:57:05 2008
@@ -98,7 +98,10 @@
 /*! \brief The value of each payload format mapping: */
 struct rtpPayloadType {
 	int isAstFormat; 	/*!< whether the following code is an AST_FORMAT */
-	int code;
+	union {
+		int code;
+		struct ast_extended_codec codec;
+	} u;
 };
 
 
@@ -167,7 +170,10 @@
 #endif
 	struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
 	int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */
-	int rtp_lookup_code_cache_code;
+	union {
+		int code;
+		struct ast_extended_codec codec;
+	} rtp_lookup_code_cache;
 	int rtp_lookup_code_cache_result;
 	struct ast_rtcp *rtcp;
 	struct ast_codec_pref pref;
@@ -1335,7 +1341,7 @@
 	rtpPT = ast_rtp_lookup_pt(rtp, payload);
 
 	/* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */
-	if (!bridged->current_RTP_PT[payload].code)
+	if (FMT_NZ(bridged->current_RTP_PT[payload].u.codec))
 		return -1;
 
 	/* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */
@@ -1343,7 +1349,11 @@
 		return -1;
 
 	/* Otherwise adjust bridged payload to match */
-	bridged_payload = ast_rtp_lookup_code(bridged, rtpPT.isAstFormat, rtpPT.code);
+	if (rtpPT.isAstFormat) {
+		bridged_payload = ast_rtp_lookup_codec(bridged, rtpPT.u.codec);
+	} else {
+		bridged_payload = ast_rtp_lookup_code(bridged, rtpPT.u.code);
+	}
 
 	/* If the mark bit has not been sent yet... do it now */
 	if (!ast_test_flag(rtp, FLAG_P2P_SENT_MARK)) {
@@ -1648,33 +1658,33 @@
 	char* type;
 	char* subtype;
 } mimeTypes[] = {
-	{{1, AST_FORMAT_G723_1}, "audio", "G723"},
-	{{1, AST_FORMAT_GSM}, "audio", "GSM"},
-	{{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
-	{{1, AST_FORMAT_ULAW}, "audio", "G711U"},
-	{{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
-	{{1, AST_FORMAT_ALAW}, "audio", "G711A"},
-	{{1, AST_FORMAT_G726}, "audio", "G726-32"},
-	{{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
-	{{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
-	{{1, AST_FORMAT_LPC10}, "audio", "LPC"},
-	{{1, AST_FORMAT_G729A}, "audio", "G729"},
-	{{1, AST_FORMAT_G729A}, "audio", "G729A"},
-	{{1, AST_FORMAT_SPEEX}, "audio", "speex"},
-	{{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
-	{{1, AST_FORMAT_G722}, "audio", "G722"},
-	{{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32"},
-	{{0, AST_RTP_DTMF}, "audio", "telephone-event"},
-	{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
-	{{0, AST_RTP_CN}, "audio", "CN"},
-	{{1, AST_FORMAT_JPEG}, "video", "JPEG"},
-	{{1, AST_FORMAT_PNG}, "video", "PNG"},
-	{{1, AST_FORMAT_H261}, "video", "H261"},
-	{{1, AST_FORMAT_H263}, "video", "H263"},
-	{{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998"},
-	{{1, AST_FORMAT_H264}, "video", "H264"},
-	{{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES"},
-	{{1, AST_FORMAT_T140}, "text", "T140"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G723_1 } } } }, "audio", "G723"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_GSM } } } }, "audio", "GSM"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ULAW } } } }, "audio", "PCMU"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ULAW } } } }, "audio", "G711U"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ALAW } } } }, "audio", "PCMA"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ALAW } } } }, "audio", "G711A"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G726 } } } }, "audio", "G726-32"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ADPCM } } } }, "audio", "DVI4"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_SLINEAR } } } }, "audio", "L16"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_LPC10 } } } }, "audio", "LPC"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G729A } } } }, "audio", "G729"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G729A } } } }, "audio", "G729A"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_SPEEX } } } }, "audio", "speex"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_ILBC } } } }, "audio", "iLBC"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G722 } } } }, "audio", "G722"},
+	{{1, { .codec = { .audio = { AST_FORMAT_AUDIO_G726_AAL2 } } } }, "audio", "AAL2-G726-32"},
+	{{0, { .code = AST_RTP_DTMF } }, "audio", "telephone-event"},
+	{{0, { .code = AST_RTP_CISCO_DTMF } }, "audio", "cisco-telephone-event"},
+	{{0, { .code = AST_RTP_CN } }, "audio", "CN"},
+	{{1, { .codec = { .image = { AST_FORMAT_IMAGE_JPEG } } } }, "video", "JPEG"},
+	{{1, { .codec = { .image = { AST_FORMAT_IMAGE_PNG } } } }, "video", "PNG"},
+	{{1, { .codec = { .video = { AST_FORMAT_VIDEO_H261 } } } }, "video", "H261"},
+	{{1, { .codec = { .video = { AST_FORMAT_VIDEO_H263 } } } }, "video", "H263"},
+	{{1, { .codec = { .video = { AST_FORMAT_VIDEO_H263_PLUS } } } }, "video", "h263-1998"},
+	{{1, { .codec = { .video = { AST_FORMAT_VIDEO_H264 } } } }, "video", "H264"},
+	{{1, { .codec = { .video = { AST_FORMAT_VIDEO_MP4_VIDEO } } } }, "video", "MP4V-ES"},
+	{{1, { .codec = { .text = { AST_FORMAT_TEXT_T140 } } } }, "text", "T140"},
 };
 
 /*! 
@@ -1688,38 +1698,38 @@
  * assigned values
  */
 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
-	[0] = {1, AST_FORMAT_ULAW},
+	[0] = {1, { .codec = { .audio = { AST_FORMAT_ULAW } } } },
 #ifdef USE_DEPRECATED_G726
-	[2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
+	[2] = {1, { .codec = { .audio = { AST_FORMAT_G726 } } } }, /* Technically this is G.721, but if Cisco can do it, so can we... */
 #endif
-	[3] = {1, AST_FORMAT_GSM},
-	[4] = {1, AST_FORMAT_G723_1},
-	[5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
-	[6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
-	[7] = {1, AST_FORMAT_LPC10},
-	[8] = {1, AST_FORMAT_ALAW},
-	[9] = {1, AST_FORMAT_G722},
-	[10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
-	[11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
-	[13] = {0, AST_RTP_CN},
-	[16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
-	[17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
-	[18] = {1, AST_FORMAT_G729A},
-	[19] = {0, AST_RTP_CN},		/* Also used for CN */
-	[26] = {1, AST_FORMAT_JPEG},
-	[31] = {1, AST_FORMAT_H261},
-	[34] = {1, AST_FORMAT_H263},
-	[97] = {1, AST_FORMAT_ILBC},
-	[98] = {1, AST_FORMAT_H263_PLUS},
-	[99] = {1, AST_FORMAT_H264},
-	[101] = {0, AST_RTP_DTMF},
-	[102] = {1, AST_FORMAT_T140},	/* Real time text chat */
-	[103] = {1, AST_FORMAT_H263_PLUS},
-	[104] = {1, AST_FORMAT_MP4_VIDEO},
-	[110] = {1, AST_FORMAT_SPEEX},
-	[111] = {1, AST_FORMAT_G726},
-	[112] = {1, AST_FORMAT_G726_AAL2},
-	[121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
+	[3] = {1, { .codec = { .audio = { AST_FORMAT_GSM } } } },
+	[4] = {1, { .codec = { .audio = { AST_FORMAT_G723_1 } } } },
+	[5] = {1, { .codec = { .audio = { AST_FORMAT_ADPCM } } } }, /* 8 kHz */
+	[6] = {1, { .codec = { .audio = { AST_FORMAT_ADPCM } } } }, /* 16 kHz */
+	[7] = {1, { .codec = { .audio = { AST_FORMAT_LPC10 } } } },
+	[8] = {1, { .codec = { .audio = { AST_FORMAT_ALAW } } } },
+	[9] = {1, { .codec = { .audio = { AST_FORMAT_G722 } } } },
+	[10] = {1, { .codec = { .audio = { AST_FORMAT_SLINEAR } } } }, /* 2 channels */
+	[11] = {1, { .codec = { .audio = { AST_FORMAT_SLINEAR } } } }, /* 1 channel */
+	[13] = {0, { .code = AST_RTP_CN } },
+	[16] = {1, { .codec = { .audio = { AST_FORMAT_ADPCM } } } }, /* 11.025 kHz */
+	[17] = {1, { .codec = { .audio = { AST_FORMAT_ADPCM } } } }, /* 22.050 kHz */
+	[18] = {1, { .codec = { .audio = { AST_FORMAT_G729A } } } },
+	[19] = {0, { .code = AST_RTP_CN } },		/* Also used for CN */
+	[26] = {1, { .codec = { .image = { AST_FORMAT_JPEG } } } },
+	[31] = {1, { .codec = { .video = { AST_FORMAT_H261 } } } },
+	[34] = {1, { .codec = { .video = { AST_FORMAT_H263 } } } },
+	[97] = {1, { .codec = { .audio = { AST_FORMAT_ILBC } } } },
+	[98] = {1, { .codec = { .video = { AST_FORMAT_H263_PLUS } } } },
+	[99] = {1, { .codec = { .video = { AST_FORMAT_H264 } } } },
+	[101] = {0, { .code = AST_RTP_DTMF } },
+	[102] = {1, { .codec = { .text = { AST_FORMAT_T140 } } } },	/* Real time text chat */
+	[103] = {1, { .codec = { .video = { AST_FORMAT_H263_PLUS } } } },
+	[104] = {1, { .codec = { .video = { AST_FORMAT_MP4_VIDEO } } } },
+	[110] = {1, { .codec = { .audio = { AST_FORMAT_SPEEX } } } },
+	[111] = {1, { .codec = { .audio = { AST_FORMAT_G726 } } } },
+	[112] = {1, { .codec = { .audio = { AST_FORMAT_G726_AAL2 } } } },
+	[121] = {0, { .code = AST_RTP_CISCO_DTMF } }, /* Must be type 121 */
 };
 
 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
@@ -1737,7 +1747,7 @@
 	}
 
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
-	rtp->rtp_lookup_code_cache_code = 0;
+	rtp->rtp_lookup_code_cache.codec = AST_FMT_NULL_MASK;
 	rtp->rtp_lookup_code_cache_result = 0;
 
 	rtp_bridge_unlock(rtp);
@@ -1756,7 +1766,7 @@
 	}
 
 	rtp->rtp_lookup_code_cache_isAstFormat = 0;
-	rtp->rtp_lookup_code_cache_code = 0;
+	rtp->rtp_lookup_code_cache.codec = AST_FMT_NULL_MASK;
 	rtp->rtp_lookup_code_cache_result = 0;
 
 	rtp_bridge_unlock(rtp);
@@ -1776,7 +1786,7 @@
 			src->current_RTP_PT[i].code; 
 	}
 	dest->rtp_lookup_code_cache_isAstFormat = 0;
-	dest->rtp_lookup_code_cache_code = 0;
+	dest->rtp_lookup_code_cache.codec = AST_FMT_NULL_MASK;
 	dest->rtp_lookup_code_cache_result = 0;
 
 	rtp_bridge_unlock(src);
@@ -1806,7 +1816,8 @@
 	struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL;
 	enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED, text_dest_res = AST_RTP_GET_FAILED;
 	enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED, text_src_res = AST_RTP_GET_FAILED;
-	int srccodec, destcodec, nat_active = 0;
+	struct ast_extended_codec srccodec, destcodec;
+	int nat_active = 0;
 
 	/* Lock channels */
 	ast_channel_lock(c0);
@@ -1858,11 +1869,11 @@
 	if (audio_src_res == AST_RTP_TRY_NATIVE && srcpr->get_codec)
 		srccodec = srcpr->get_codec(c1);
 	else
-		srccodec = 0;
+		srccodec = AST_FMT_NULL_MASK;
 	if (audio_dest_res == AST_RTP_TRY_NATIVE && destpr->get_codec)
 		destcodec = destpr->get_codec(c0);
 	else
-		destcodec = 0;
+		destcodec = AST_FMT_NULL_MASK;
 	/* Ensure we have at least one matching codec */
 	if (!(srccodec & destcodec)) {
 		ast_channel_unlock(c0);
@@ -2006,10 +2017,12 @@
 		    strcasecmp(mimeType, mimeTypes[i].type) == 0) {
 			found = 1;
 			rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
-			if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) &&
+			if ((mimeTypes[i].payloadType.u.codec.audio[0] == AST_FORMAT_G726) &&
 			    mimeTypes[i].payloadType.isAstFormat &&
-			    (options & AST_RTP_OPT_G726_NONSTANDARD))
-				rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2;
+			    (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+				rtp->current_RTP_PT[pt].codec = AST_FMT_NULL_MASK;
+				rtp->current_RTP_PT[pt].codec.audio[0] = AST_FORMAT_AUDIO_G726_AAL2;
+			}
 			break;
 		}
 	}
@@ -2021,19 +2034,20 @@
 
 /*! \brief Return the union of all of the codecs that were set by rtp_set...() calls 
  * They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
-void ast_rtp_get_current_formats(struct ast_rtp* rtp,
-				 int* astFormats, int* nonAstFormats)
+void ast_rtp_get_current_formats(struct ast_rtp *rtp,
+				 struct ast_extended_codec *astFormats, int *nonAstFormats)
 {
 	int pt;
 	
 	rtp_bridge_lock(rtp);
 	
-	*astFormats = *nonAstFormats = 0;
+	*astFormats = AST_FMT_NULL_MASK;
+	*nonAstFormats = 0;
 	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
 		if (rtp->current_RTP_PT[pt].isAstFormat) {
-			*astFormats |= rtp->current_RTP_PT[pt].code;
+			*astFormats = FMT_OR(*astFormats, rtp->current_RTP_PT[pt].u.codec);
 		} else {
-			*nonAstFormats |= rtp->current_RTP_PT[pt].code;
+			*nonAstFormats |= rtp->current_RTP_PT[pt].u.code;
 		}
 	}
 
@@ -2044,7 +2058,8 @@
 {
 	struct rtpPayloadType result;
 
-	result.isAstFormat = result.code = 0;
+	result.u.codec = AST_FMT_NULL_MASK;
+	result.isAstFormat = 0;
 
 	if (pt < 0 || pt > MAX_RTP_PT) 
 		return result; /* bogus payload type */
@@ -2055,21 +2070,21 @@
 	rtp_bridge_unlock(rtp);
 
 	/* If it doesn't exist, check our static RTP type list, just in case */
-	if (!result.code) 
+	if (FMT_NOT(result.u.codec)) 
 		result = static_RTP_PT[pt];
 
 	return result;
 }
 
 /*! \brief Looks up an RTP code out of our *static* outbound list */
-int ast_rtp_lookup_code(struct ast_rtp* rtp, const int isAstFormat, const int code)
+int ast_rtp_lookup_code(struct ast_rtp* rtp, const int code)
 {
 	int pt = 0;
 
 	rtp_bridge_lock(rtp);
 
-	if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
-		code == rtp->rtp_lookup_code_cache_code) {
+	if (rtp->rtp_lookup_code_cache_isAstFormat == 0 &&
+		code == rtp->rtp_lookup_code_cache.code) {
 		/* Use our cached mapping, to avoid the overhead of the loop below */
 		pt = rtp->rtp_lookup_code_cache_result;
 		rtp_bridge_unlock(rtp);
@@ -2078,9 +2093,10 @@
 
 	/* Check the dynamic list first */
 	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
-		if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
-			rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
-			rtp->rtp_lookup_code_cache_code = code;
+		if (rtp->current_RTP_PT[pt].u.code == code) {
+			rtp->rtp_lookup_code_cache_isAstFormat = 0;
+			rtp->rtp_lookup_code_cache.codec = AST_FMT_NULL_MASK;
+			rtp->rtp_lookup_code_cache.code = code;
 			rtp->rtp_lookup_code_cache_result = pt;
 			rtp_bridge_unlock(rtp);
 			return pt;
@@ -2089,9 +2105,10 @@
 
 	/* Then the static list */
 	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
-		if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) {
-			rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
-  			rtp->rtp_lookup_code_cache_code = code;
+		if (static_RTP_PT[pt].u.code == code) {
+			rtp->rtp_lookup_code_cache_isAstFormat = 0;
+			rtp->rtp_lookup_code_cache.codec = AST_FMT_NULL_MASK;
+  			rtp->rtp_lookup_code_cache.code = code;
 			rtp->rtp_lookup_code_cache_result = pt;
 			rtp_bridge_unlock(rtp);
 			return pt;
@@ -2103,15 +2120,54 @@
 	return -1;
 }
 
-const char *ast_rtp_lookup_mime_subtype(const int isAstFormat, const int code,
-				  enum ast_rtp_options options)
+int ast_rtp_lookup_codec(struct ast_rtp* rtp, const struct ast_extended_codec code)
+{
+	int pt = 0;
+
+	rtp_bridge_lock(rtp);
+
+	if (rtp->rtp_lookup_code_cache_isAstFormat == 1 &&
+		FMT_EQ(code, rtp->rtp_lookup_code_cache.codec)) {
+		/* Use our cached mapping, to avoid the overhead of the loop below */
+		pt = rtp->rtp_lookup_code_cache_result;
+		rtp_bridge_unlock(rtp);
+		return pt;
+	}
+
+	/* Check the dynamic list first */
+	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
+		if (FMT_EQ(rtp->current_RTP_PT[pt].u.codec, code) && rtp->current_RTP_PT[pt].isAstFormat == 1) {
+			rtp->rtp_lookup_code_cache_isAstFormat = 1;
+			rtp->rtp_lookup_code_cache.codec = code;
+			rtp->rtp_lookup_code_cache_result = pt;
+			rtp_bridge_unlock(rtp);
+			return pt;
+		}
+	}
+
+	/* Then the static list */
+	for (pt = 0; pt < MAX_RTP_PT; ++pt) {
+		if (FMT_EQ(static_RTP_PT[pt].u.codec, code) && static_RTP_PT[pt].isAstFormat == 1) {
+			rtp->rtp_lookup_code_cache_isAstFormat = 1;
+  			rtp->rtp_lookup_code_cache.codec = code;
+			rtp->rtp_lookup_code_cache_result = pt;
+			rtp_bridge_unlock(rtp);
+			return pt;
+		}
+	}
+
+	rtp_bridge_unlock(rtp);
+
+	return -1;
+}
+
+const char *ast_rtp_lookup_codec_mime_subtype(const struct ast_extended_codec code, enum ast_rtp_options options)
 {
 	unsigned int i;
 
 	for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) {
-		if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) {
-			if (isAstFormat &&
-			    (code == AST_FORMAT_G726_AAL2) &&
+		if (FMT_EQ(mimeTypes[i].payloadType.u.codec, code) && (mimeTypes[i].payloadType.isAstFormat == 1)) {
+			if ((code == AST_FORMAT_G726_AAL2) &&
 			    (options & AST_RTP_OPT_G726_NONSTANDARD))
 				return "G726-32";
 			else
@@ -2122,8 +2178,20 @@
 	return "";
 }
 
-char *ast_rtp_lookup_mime_multiple(char *buf, size_t size, const int capability,
-				   const int isAstFormat, enum ast_rtp_options options)
+const char *ast_rtp_lookup_noncodec_mime_subtype(const int code, enum ast_rtp_options options)
+{
+	unsigned int i;
+
+	for (i = 0; i < sizeof(mimeTypes) / sizeof(mimeTypes[0]); ++i) {
+		if (mimeTypes[i].payloadType.u.code == code) {
+			return mimeTypes[i].subtype;
+		}
+	}
+
+	return "";
+}
+
+char *ast_rtp_lookup_noncodec_mime_multiple(char *buf, size_t size, const int capability, enum ast_rtp_options options)
 {
 	int format;
 	unsigned len;
@@ -2142,13 +2210,56 @@
 
 	for (format = 1; format < AST_RTP_MAX; format <<= 1) {
 		if (capability & format) {
-			const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format, options);
-
-			snprintf(end, size, "%s|", name);
-			len = strlen(end);
+			const char *name = ast_rtp_lookup_noncodec_mime_subtype(format, options);
+
+			len = snprintf(end, size, "%s|", name);
 			end += len;
 			size -= len;
 		}
+	}
+
+	if (start == end)
+		ast_copy_string(start, "nothing)", size); 
+	else if (size > 1)
+		*(end -1) = ')';
+	
+	return buf;
+}
+
+char *ast_rtp_lookup_codec_mime_multiple(char *buf, size_t size, const struct ast_extended_codec capability, enum ast_rtp_options options)
+{
+	union {
+		struct ast_extended_codec format;
+		int bits[sizeof(struct ast_extended_codec) / sizeof(int)];
+	} u = { { { 0 } } };
+	int page, bits;
+	unsigned len;
+	char *end = buf;
+	char *start = buf;
+	struct ast_str *str = ast_str_alloca(BITSTRING_SIZE);
+
+	if (!buf || !size)
+		return NULL;
+
+	snprintf(end, size, "%s (", ast_codec2bitstring(capability, &str));
+
+	len = strlen(end);
+	end += len;
+	size -= len;
+	start = end;
+
+	for (page = 0; page < sizeof(struct ast_extended_codec) / sizeof(int); page++) {
+		for (bits = 0; bits < sizeof(int) * 8; bits++) {
+			u.bits[page] = 1 << bits;
+			if (FMT_NZ(FMT_AND(u.format, capability))) {
+				const char *name = ast_rtp_lookup_codec_mime_subtype(u.format, options);
+
+				len = snprintf(end, size, "%s|", name);
+				end += len;
+				size -= len;
+			}
+		}
+		u.bits[page] = 0;
 	}
 
 	if (start == end)
@@ -2568,7 +2679,7 @@
 	if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
 		return 0;
 
-	payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
+	payload = ast_rtp_lookup_code(rtp, AST_RTP_DTMF);
 
 	rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
 	rtp->send_duration = 160;
@@ -2966,7 +3077,7 @@
 	int payload;
 	char data[256];
 	level = 127 - (level & 0x7f);
-	payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN);
+	payload = ast_rtp_lookup_code(rtp, AST_RTP_CN);
 
 	/* If we have no peer, return immediately */	
 	if (!rtp->them.sin_addr.s_addr)
@@ -3118,15 +3229,17 @@
 	return &rtp->pref;
 }
 
-int ast_rtp_codec_getformat(int pt)
-{
-	if (pt < 0 || pt > MAX_RTP_PT)
-		return 0; /* bogus payload type */
-
-	if (static_RTP_PT[pt].isAstFormat)
-		return static_RTP_PT[pt].code;
-	else
-		return 0;
+struct ast_extended_codec ast_rtp_codec_getformat(int pt)
+{
+	if (pt < 0 || pt > MAX_RTP_PT) {
+		return AST_FMT_NULL_MASK; /* bogus payload type */
+	}
+
+	if (static_RTP_PT[pt].isAstFormat) {
+		return static_RTP_PT[pt].u.codec;
+	} else {
+		return AST_FMT_NULL_MASK;
+	}
 }
 
 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
@@ -3135,7 +3248,6 @@
 	int codec;
 	int hdrlen = 12;
 	int subclass;
-	
 
 	/* If we have no peer, return immediately */	
 	if (!rtp->them.sin_addr.s_addr)
@@ -3152,35 +3264,35 @@
 	}
 
 	/* The bottom bit of a video subclass contains the marker bit */
-	subclass = _f->subclass;
 	if (_f->frametype == AST_FRAME_VIDEO)
-		subclass &= ~0x1;
-
-	codec = ast_rtp_lookup_code(rtp, 1, subclass);
+		subclass = 1;
+
+	codec = ast_rtp_lookup_codec(rtp, _f->codec);
 	if (codec < 0) {
-		ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
+		ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->codec));
 		return -1;
 	}
 
-	if (rtp->lasttxformat != subclass) {
+	if (rtp->lasttxformat != codec) {
 		/* New format, reset the smoother */
-		ast_debug(1, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
-		rtp->lasttxformat = subclass;
+		ast_debug(1, "Ooh, format changed from %d to %d\n", rtp->lasttxformat, codec);
+		rtp->lasttxformat = codec;
 		if (rtp->smoother)
 			ast_smoother_free(rtp->smoother);
 		rtp->smoother = NULL;
 	}
 
-	if (!rtp->smoother && subclass != AST_FORMAT_SPEEX && subclass != AST_FORMAT_G723_1) {
-		struct ast_format_list fmt = ast_codec_pref_getsize(&rtp->pref, subclass);
+	if (!rtp->smoother && _f->codec.audio[0] != AST_FORMAT_AUDIO_SPEEX && _f->codec.audio[0] != AST_FORMAT_AUDIO_G723_1) {
+		struct ast_format_list fmt = ast_codec_pref_getsize(&rtp->pref, _f->codec);
+		struct ast_str *str = ast_str_alloca(BITSTRING_SIZE);
 		if (fmt.inc_ms) { /* if codec parameters is set / avoid division by zero */
 			if (!(rtp->smoother = ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) {
-				ast_log(LOG_WARNING, "Unable to create smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
+				ast_log(LOG_WARNING, "Unable to create smoother: format: %s ms: %d len: %d\n", ast_codec2bitstring(_f->codec, &str), fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
 				return -1;
 			}
 			if (fmt.flags)
 				ast_smoother_set_flags(rtp->smoother, fmt.flags);
-			ast_debug(1, "Created smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
+			ast_debug(1, "Created smoother: format: %s ms: %d len: %d\n", ast_codec2bitstring(_f->codec, &str), fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
 		}
 	}
 	if (rtp->smoother) {
@@ -3191,7 +3303,7 @@
 		}
 
 		while ((f = ast_smoother_read(rtp->smoother)) && (f->data)) {
-			if (f->subclass == AST_FORMAT_G722) {
+			if (f->codec.audio[0] == AST_FORMAT_AUDIO_G722) {
 				/* G.722 is silllllllllllllly */
 				f->samples /= 2;
 			}
@@ -3241,11 +3353,11 @@
 }
 
 /*! \brief Bridge loop for true native bridge (reinvite) */
-static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, struct ast_rtp *vp0, struct ast_rtp *vp1, struct ast_rtp *tp0, struct ast_rtp *tp1, struct ast_rtp_protocol *pr0, struct ast_rtp_protocol *pr1, int codec0, int codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
+static enum ast_bridge_result bridge_native_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, struct ast_rtp *vp0, struct ast_rtp *vp1, struct ast_rtp *tp0, struct ast_rtp *tp1, struct ast_rtp_protocol *pr0, struct ast_rtp_protocol *pr1, struct ast_extended_codec codec0, struct ast_extended_codec codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
 {
 	struct ast_frame *fr = NULL;
 	struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, };
-	int oldcodec0 = codec0, oldcodec1 = codec1;
+	struct ast_extended_codec oldcodec0 = codec0, oldcodec1 = codec1;
 	struct sockaddr_in ac1 = {0,}, vac1 = {0,}, tac1 = {0,}, ac0 = {0,}, vac0 = {0,}, tac0 = {0,};
 	struct sockaddr_in t1 = {0,}, vt1 = {0,}, tt1 = {0,}, t0 = {0,}, vt0 = {0,}, tt0 = {0,};
 	
@@ -3289,10 +3401,10 @@
 		    (c0->monitor || c0->audiohooks || c1->monitor || c1->audiohooks)) {
 			ast_debug(1, "Oooh, something is weird, backing out\n");
 			if (c0->tech_pvt == pvt0)
-				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, 0, 0))
+				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
 			if (c1->tech_pvt == pvt1)
-				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, 0, 0))
+				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
 			ast_poll_channel_del(c0, c1);
 			return AST_BRIDGE_RETRY;
@@ -3316,19 +3428,20 @@
 		if ((inaddrcmp(&t1, &ac1)) ||
 		    (vp1 && inaddrcmp(&vt1, &vac1)) ||
 		    (tp1 && inaddrcmp(&tt1, &tac1)) ||
-		    (codec1 != oldcodec1)) {
-			ast_debug(2, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
-				c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1);
-			ast_debug(2, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n",
-				c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), codec1);
-			ast_debug(2, "Oooh, '%s' changed end taddress to %s:%d (format %d)\n",
-				c1->name, ast_inet_ntoa(tt1.sin_addr), ntohs(tt1.sin_port), codec1);
-			ast_debug(2, "Oooh, '%s' was %s:%d/(format %d)\n",
-				c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
-			ast_debug(2, "Oooh, '%s' was %s:%d/(format %d)\n",
-				c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
-			ast_debug(2, "Oooh, '%s' was %s:%d/(format %d)\n",
-				c1->name, ast_inet_ntoa(tac1.sin_addr), ntohs(tac1.sin_port), oldcodec1);
+		    !FMT_EQ(codec1, oldcodec1)) {
+			struct ast_str *str = ast_str_alloca(BITSTRING_SIZE);
+			ast_debug(2, "Oooh, '%s' changed end address to %s:%d (format %s)\n",
+				c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), ast_codec2bitstring(codec1, &str));
+			ast_debug(2, "Oooh, '%s' changed end vaddress to %s:%d (format %s)\n",
+				c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), ast_codec2bitstring(codec1, &str));
+			ast_debug(2, "Oooh, '%s' changed end taddress to %s:%d (format %s)\n",
+				c1->name, ast_inet_ntoa(tt1.sin_addr), ntohs(tt1.sin_port), ast_codec2bitstring(codec1, &str));
+			ast_debug(2, "Oooh, '%s' was %s:%d/(format %s)\n",
+				c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), ast_codec2bitstring(oldcodec1, &str));
+			ast_debug(2, "Oooh, '%s' was %s:%d/(format %s)\n",
+				c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), ast_codec2bitstring(oldcodec1, &str));
+			ast_debug(2, "Oooh, '%s' was %s:%d/(format %s)\n",
+				c1->name, ast_inet_ntoa(tac1.sin_addr), ntohs(tac1.sin_port), ast_codec2bitstring(oldcodec1, &str));
 			if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, tt1.sin_addr.s_addr ? tp1 : NULL, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE)))
 				ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
 			memcpy(&ac1, &t1, sizeof(ac1));
@@ -3339,10 +3452,10 @@
 		if ((inaddrcmp(&t0, &ac0)) ||
 		    (vp0 && inaddrcmp(&vt0, &vac0)) ||
 		    (tp0 && inaddrcmp(&tt0, &tac0))) {
-			ast_debug(2, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
-				c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0);
-			ast_debug(2, "Oooh, '%s' was %s:%d/(format %d)\n",
-				c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
+			ast_debug(2, "Oooh, '%s' changed end address to %s:%d (format %s)\n",
+				c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), ast_getformatname(codec0));
+			ast_debug(2, "Oooh, '%s' was %s:%d/(format %s)\n",
+				c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), ast_getformatname(oldcodec0));
 			if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, tt0.sin_addr.s_addr ? tp0 : NULL, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)))
 				ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
 			memcpy(&ac0, &t0, sizeof(ac0));
@@ -3354,9 +3467,9 @@
 		/* Wait for frame to come in on the channels */
 		if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) {
 			if (!timeoutms) {
-				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, 0, 0))
+				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
-				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, 0, 0))
+				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
 				return AST_BRIDGE_RETRY;
 			}
@@ -3375,10 +3488,10 @@
 			*rc = who;
 			ast_debug(1, "Oooh, got a %s\n", fr ? "digit" : "hangup");
 			if (c0->tech_pvt == pvt0)
-				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, 0, 0))
+				if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
 			if (c1->tech_pvt == pvt1)
-				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, 0, 0))
+				if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 					ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
 			ast_poll_channel_del(c0, c1);
 			return AST_BRIDGE_COMPLETE;
@@ -3391,9 +3504,9 @@
 				if (fr->subclass == AST_CONTROL_HOLD) {
 					/* If we someone went on hold we want the other side to reinvite back to us */
 					if (who == c0)
-						pr1->set_rtp_peer(c1, NULL, NULL, NULL, 0, 0);
+						pr1->set_rtp_peer(c1, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0);
 					else
-						pr0->set_rtp_peer(c0, NULL, NULL, NULL, 0, 0);
+						pr0->set_rtp_peer(c0, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0);
 				} else if (fr->subclass == AST_CONTROL_UNHOLD) {
 					/* If they went off hold they should go back to being direct */
 					if (who == c0)
@@ -3442,9 +3555,9 @@
 
 	ast_poll_channel_del(c0, c1);
 
-	if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, 0, 0))
+	if (pr0->set_rtp_peer(c0, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 		ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name);
-	if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, 0, 0))
+	if (pr1->set_rtp_peer(c1, NULL, NULL, NULL, AST_FMT_NULL_MASK, 0))
 		ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name);
 
 	return AST_BRIDGE_FAILED;
@@ -3578,7 +3691,7 @@
 	cs[2] = NULL;
 	for (;;) {
 		/* If the underlying formats have changed force this bridge to break */
-		if ((c0->rawreadformat != c1->rawwriteformat) || (c1->rawreadformat != c0->rawwriteformat)) {
+		if (!FMT_EQ(c0->rawreadformat, c1->rawwriteformat) || !FMT_EQ(c1->rawreadformat, c0->rawwriteformat)) {
 			ast_debug(3, "p2p-rtp-bridge: Oooh, formats changed, backing out\n");
 			res = AST_BRIDGE_FAILED_NOWARN;
 			break;
@@ -3732,7 +3845,7 @@
 	enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = AST_RTP_GET_FAILED, text_p0_res = AST_RTP_GET_FAILED;
 	enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = AST_RTP_GET_FAILED, text_p1_res = AST_RTP_GET_FAILED;
 	enum ast_bridge_result res = AST_BRIDGE_FAILED;
-	int codec0 = 0, codec1 = 0;
+	struct ast_extended_codec codec0 = { { 0 } }, codec1 = { { 0 } };
 	void *pvt0 = NULL, *pvt1 = NULL;
 
 	/* Lock channels */
@@ -3835,11 +3948,12 @@
 	}
 
 	/* Get codecs from both sides */
-	codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0;
-	codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0;
-	if (codec0 && codec1 && !(codec0 & codec1)) {
+	codec0 = pr0->get_codec ? pr0->get_codec(c0) : AST_FMT_NULL_MASK;
+	codec1 = pr1->get_codec ? pr1->get_codec(c1) : AST_FMT_NULL_MASK;
+	if (FMT_NZ(codec0) && FMT_NZ(codec1) && FMT_NOT(FMT_AND(codec0, codec1))) {
+		struct ast_str *str[2] = { ast_str_alloca(BITSTRING_SIZE), ast_str_alloca(BITSTRING_SIZE) };
 		/* Hey, we can't do native bridging if both parties speak different codecs */
-		ast_debug(3, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1);
+		ast_debug(3, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n", ast_codec2bitstring(codec0, &str[0]), ast_codec2bitstring(codec1, &str[1]));
 		ast_channel_unlock(c0);
 		ast_channel_unlock(c1);
 		return AST_BRIDGE_FAILED_NOWARN;
@@ -3850,7 +3964,7 @@
 		struct ast_format_list fmt0, fmt1;
 
 		/* In order to do Packet2Packet bridging both sides must be in the same rawread/rawwrite */
-		if (c0->rawreadformat != c1->rawwriteformat || c1->rawreadformat != c0->rawwriteformat) {
+		if (!FMT_EQ(c0->rawreadformat, c1->rawwriteformat) || !FMT_EQ(c1->rawreadformat, c0->rawwriteformat)) {
 			ast_debug(1, "Cannot packet2packet bridge - raw formats are incompatible\n");
 			ast_channel_unlock(c0);
 			ast_channel_unlock(c1);




More information about the asterisk-commits mailing list