diff --git a/addons/chan_mobile.c b/addons/chan_mobile.c
index 29d14e036fe1edc2affc810e00d6acc137b06de4..dd48f933eb05aae7d5ea8a2f59bf54a4f52a0acb 100644
--- a/addons/chan_mobile.c
+++ b/addons/chan_mobile.c
@@ -71,7 +71,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define DEVICE_FRAME_FORMAT AST_FORMAT_SLINEAR
 #define CHANNEL_FRAME_SIZE 320
 
-static format_t prefformat = DEVICE_FRAME_FORMAT;
+static struct ast_format prefformat;
 
 static int discovery_interval = 60;			/* The device discovery interval, default 60 seconds. */
 static pthread_t discovery_thread = AST_PTHREADT_NULL;	/* The discovery thread */
@@ -196,7 +196,7 @@ static char *mblsendsms_desc =
 
 static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num,
 		const struct ast_channel *requestor);
-static struct ast_channel *mbl_request(const char *type, format_t format,
+static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
 		const struct ast_channel *requestor, void *data, int *cause);
 static int mbl_call(struct ast_channel *ast, char *dest, int timeout);
 static int mbl_hangup(struct ast_channel *ast);
@@ -450,10 +450,9 @@ static struct msg_queue_entry *msg_queue_head(struct mbl_pvt *pvt);
  * channel stuff
  */
 
-static const struct ast_channel_tech mbl_tech = {
+static struct ast_channel_tech mbl_tech = {
 	.type = "Mobile",
 	.description = "Bluetooth Mobile Device Channel Driver",
-	.capabilities = AST_FORMAT_SLINEAR,
 	.requester = mbl_request,
 	.call = mbl_call,
 	.hangup = mbl_hangup,
@@ -844,11 +843,11 @@ static struct ast_channel *mbl_new(int state, struct mbl_pvt *pvt, char *cid_num
 	}
 
 	chn->tech = &mbl_tech;
-	chn->nativeformats = prefformat;
-	chn->rawreadformat = prefformat;
-	chn->rawwriteformat = prefformat;
-	chn->writeformat = prefformat;
-	chn->readformat = prefformat;
+	ast_format_cap_add(chn->nativeformats, &prefformat);
+	ast_format_copy(&chn->rawreadformat, &prefformat);
+	ast_format_copy(&chn->rawwriteformat, &prefformat);
+	ast_format_copy(&chn->writeformat, &prefformat);
+	ast_format_copy(&chn->readformat, &prefformat);
 	chn->tech_pvt = pvt;
 
 	if (state == AST_STATE_RING)
@@ -867,7 +866,7 @@ e_return:
 	return NULL;
 }
 
-static struct ast_channel *mbl_request(const char *type, format_t format,
+static struct ast_channel *mbl_request(const char *type, struct ast_format_cap *cap,
 		const struct ast_channel *requestor, void *data, int *cause)
 {
 
@@ -875,7 +874,6 @@ static struct ast_channel *mbl_request(const char *type, format_t format,
 	struct mbl_pvt *pvt;
 	char *dest_dev = NULL;
 	char *dest_num = NULL;
-	format_t oldformat;
 	int group = -1;
 
 	if (!data) {
@@ -884,10 +882,9 @@ static struct ast_channel *mbl_request(const char *type, format_t format,
 		return NULL;
 	}
 
-	oldformat = format;
-	format &= (AST_FORMAT_SLINEAR);
-	if (!format) {
-		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
+	if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
+		char tmp[256];
+		ast_log(LOG_WARNING, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		*cause = AST_CAUSE_FACILITY_NOT_IMPLEMENTED;
 		return NULL;
 	}
@@ -1099,7 +1096,7 @@ static struct ast_frame *mbl_read(struct ast_channel *ast)
 
 	memset(&pvt->fr, 0x00, sizeof(struct ast_frame));
 	pvt->fr.frametype = AST_FRAME_VOICE;
-	pvt->fr.subclass.codec = DEVICE_FRAME_FORMAT;
+	ast_format_set(&pvt->fr.subclass.format, DEVICE_FRAME_FORMAT, 0);
 	pvt->fr.src = "Mobile";
 	pvt->fr.offset = AST_FRIENDLY_OFFSET;
 	pvt->fr.mallocd = 0;
@@ -4534,6 +4531,7 @@ static int unload_module(void)
 	if (sdp_session)
 		sdp_close(sdp_session);
 
+	mbl_tech.capabilities = ast_format_cap_destroy(mbl_tech.capabilities);
 	return 0;
 }
 
@@ -4542,6 +4540,11 @@ static int load_module(void)
 
 	int dev_id, s;
 
+	if (!(mbl_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_set(&prefformat, DEVICE_FRAME_FORMAT, 0);
+	ast_format_cap_add(mbl_tech.capabilities, &prefformat);
 	/* Check if we have Bluetooth, no point loading otherwise... */
 	dev_id = hci_get_route(NULL);
 	s = hci_open_dev(dev_id);
diff --git a/addons/chan_ooh323.c b/addons/chan_ooh323.c
index a49e3a882cd2f27fe7c37f48fff6189fbdb0d4ff..df4965bbda60e237051b8f18623259f95bcf0696 100644
--- a/addons/chan_ooh323.c
+++ b/addons/chan_ooh323.c
@@ -66,7 +66,7 @@ static struct ast_jb_conf default_jbconf =
 static struct ast_jb_conf global_jbconf;
 
 /* Channel Definition */
-static struct ast_channel *ooh323_request(const char *type, format_t format, 
+static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
 			const struct ast_channel *requestor,  void *data, int *cause);
 static int ooh323_digit_begin(struct ast_channel *ast, char digit);
 static int ooh323_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -82,7 +82,7 @@ static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
 static enum ast_rtp_glue_result ooh323_get_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
 static enum ast_rtp_glue_result ooh323_get_vrtp_peer(struct ast_channel *chan, struct ast_rtp_instance **rtp);
 static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, 
-          struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active);
+          struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active);
 
 static struct ast_udptl *ooh323_get_udptl_peer(struct ast_channel *chan);
 static int ooh323_set_udptl_peer(struct ast_channel *chan, struct ast_udptl *udptl);
@@ -92,10 +92,9 @@ static void print_codec_to_cli(int fd, struct ast_codec_pref *pref);
 struct ooh323_peer *find_friend(const char *name, int port);
 
 
-static const struct ast_channel_tech ooh323_tech = {
+static struct ast_channel_tech ooh323_tech = {
 	.type = type,
 	.description = tdesc,
-	.capabilities = -1,
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = ooh323_request,
 	.send_digit_begin = ooh323_digit_begin,
@@ -172,9 +171,9 @@ static struct ooh323_pvt {
 	char callee_url[AST_MAX_EXTENSION];
  
 	int port;
-	format_t readformat;   /* negotiated read format */
-	format_t writeformat;  /* negotiated write format */
-	format_t capability;
+	struct ast_format readformat;   /* negotiated read format */
+	struct ast_format writeformat;  /* negotiated write format */
+	struct ast_format_cap *cap;
 	struct ast_codec_pref prefs;
 	int dtmfmode;
 	int dtmfcodec;
@@ -204,7 +203,7 @@ struct ooh323_user{
 	unsigned    inUse;
 	char        accountcode[20];
 	int         amaflags;
-	format_t    capability;
+	struct ast_format_cap *cap;
 	struct ast_codec_pref prefs;
 	int         dtmfmode;
 	int	    dtmfcodec;
@@ -225,7 +224,7 @@ struct ooh323_peer{
 	char        name[256];
 	unsigned    outgoinglimit;
 	unsigned    outUse;
-	format_t    capability;
+	struct ast_format_cap *cap;
 	struct ast_codec_pref prefs;
 	char        accountcode[20];
 	int         amaflags;
@@ -286,7 +285,7 @@ static int  gPort = 1720;
 static char gIP[20];
 static char gCallerID[AST_MAX_EXTENSION] = "";
 static struct ooAliases *gAliasList;
-static format_t gCapability = AST_FORMAT_ULAW;
+static struct ast_format_cap *gCap;
 static struct ast_codec_pref gPrefs;
 static int  gDTMFMode = H323_DTMF_RFC2833;
 static int  gDTMFCodec = 101;
@@ -337,14 +336,14 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
 
 
 static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
-                                             const char *host, int capability, const char *linkedid) 
+                                             const char *host, struct ast_format_cap *cap, const char *linkedid) 
 {
 	struct ast_channel *ch = NULL;
-	int fmt = 0;
+	struct ast_format tmpfmt;
 	if (gH323Debug)
-		ast_verbose("---   ooh323_new - %s, %d\n", host, capability);
-
+		ast_verbose("---   ooh323_new - %s\n", host);
 
+	ast_format_clear(&tmpfmt);
 	/* Don't hold a h323 pvt lock while we allocate a channel */
 	ast_mutex_unlock(&i->lock);
    	ch = ast_channel_alloc(1, state, i->callerid_num, i->callerid_name, 
@@ -360,12 +359,14 @@ static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
 		ast_channel_lock(ch);
 		ch->tech = &ooh323_tech;
 
-		if (capability)
-			fmt = ast_best_codec(capability);
-		if (!fmt) 
-			fmt = ast_codec_pref_index(&i->prefs, 0);
+		if (cap)
+			ast_best_codec(cap, &tmpfmt);
+		if (!tmpfmt.id)
+			ast_codec_pref_index(&i->prefs, 0, &tmpfmt);
 
-		ch->nativeformats = ch->rawwriteformat = ch->rawreadformat = fmt;
+		ast_format_cap_add(ch->nativeformats, &tmpfmt);
+		ast_format_copy(&ch->rawwriteformat, &tmpfmt);
+		ast_format_copy(&ch->rawreadformat, &tmpfmt);
 
 		ast_channel_set_fd(ch, 0, ast_rtp_instance_fd(i->rtp, 0));
 		ast_channel_set_fd(ch, 1, ast_rtp_instance_fd(i->rtp, 1));
@@ -377,8 +378,8 @@ static struct ast_channel *ooh323_new(struct ooh323_pvt *i, int state,
 			ch->rings = 1;
 
 		ch->adsicpe = AST_ADSI_UNAVAILABLE;
-		ast_set_write_format(ch, fmt);
-		ast_set_read_format(ch, fmt);
+		ast_set_write_format(ch, &tmpfmt);
+		ast_set_read_format(ch, &tmpfmt);
 		ch->tech_pvt = i;
 		i->owner = ch;
 		ast_module_ref(myself);
@@ -472,6 +473,11 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
 		ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
 		return NULL;
 	}
+	if (!(pvt->cap = ast_format_cap_alloc_nolock())) {
+		ast_free(pvt);
+		ast_log(LOG_ERROR, "Couldn't allocate private ooh323 structure\n");
+		return NULL;
+	}
 
 	ast_mutex_init(&pvt->lock);
 	ast_mutex_lock(&pvt->lock);
@@ -529,7 +535,7 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
 	ast_copy_string(pvt->accountcode, gAccountcode, sizeof(pvt->accountcode));
 
 	pvt->amaflags = gAMAFLAGS;
-	pvt->capability = gCapability;
+	ast_format_cap_copy(pvt->cap, gCap);
 	memcpy(&pvt->prefs, &gPrefs, sizeof(pvt->prefs));
 
 	ast_mutex_unlock(&pvt->lock); 
@@ -549,7 +555,7 @@ static struct ooh323_pvt *ooh323_alloc(int callref, char *callToken)
 /*
 	Possible data values - peername, exten/peername, exten@ip
  */
-static struct ast_channel *ooh323_request(const char *type, format_t format,
+static struct ast_channel *ooh323_request(const char *type, struct ast_format_cap *cap,
 		const struct ast_channel *requestor, void *data, int *cause)
 
 {
@@ -560,17 +566,14 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
 	char *ext = NULL;
 	char tmp[256];
 	char formats[FORMAT_STRING_SIZE];
-	int oldformat;
 	int port = 0;
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_request - data %s format %s\n", (char*)data,  
-										ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,format));
+										ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
 
-	oldformat = format;
-	format &= AST_FORMAT_AUDIO_MASK;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%lld'\n", (long long) format);
+	if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
 		return NULL;
 	}
 
@@ -633,7 +636,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
 		if (ext)
 			ast_copy_string(p->exten, ext, sizeof(p->exten));
 
-		p->capability = peer->capability;
+		ast_format_cap_copy(p->cap, peer->cap);
 		memcpy(&p->prefs, &peer->prefs, sizeof(struct ast_codec_pref));
 		p->dtmfmode |= peer->dtmfmode;
 		p->dtmfcodec  = peer->dtmfcodec;
@@ -667,7 +670,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
 		p->dtmfcodec = gDTMFCodec;
 		p->t38support = gT38Support;
 		p->rtptimeout = gRTPTimeout;
-		p->capability = gCapability;
+		ast_format_cap_copy(p->cap, gCap);
 		p->rtdrinterval = gRTDRInterval;
 		p->rtdrcount = gRTDRCount;
 		p->faststart = gFastStart;
@@ -686,7 +689,7 @@ static struct ast_channel *ooh323_request(const char *type, format_t format,
 	}
 
 
-	chan = ooh323_new(p, AST_STATE_DOWN, p->username, format,
+	chan = ooh323_new(p, AST_STATE_DOWN, p->username, cap,
 				 requestor ? requestor->linkedid : NULL);
 	
 	ast_mutex_unlock(&p->lock);
@@ -1140,16 +1143,16 @@ static int ooh323_write(struct ast_channel *ast, struct ast_frame *f)
 			}
 
 
-			if (!(f->subclass.codec & ast->nativeformats)) {
-				if (ast->nativeformats != 0) {
+			if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
+				if (!(ast_format_cap_is_empty(ast->nativeformats))) {
 					ast_log(LOG_WARNING,
 							"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
-							ast_getformatname(f->subclass.codec),
+							ast_getformatname(&f->subclass.format),
 							ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
-							ast_getformatname(ast->readformat),
-							ast_getformatname(ast->writeformat));
+							ast_getformatname(&ast->readformat),
+							ast_getformatname(&ast->writeformat));
 
-					ast_set_write_format(ast, f->subclass.codec);
+					ast_set_write_format(ast, &f->subclass.format);
 				} else {
 					/* ast_set_write_format(ast, f->subclass);
 					ast->nativeformats = f->subclass; */
@@ -1409,14 +1412,14 @@ static int ooh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan
 }
 
 
-void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
+void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes)
 {
 	struct ooh323_pvt *p = NULL;
 	char formats[FORMAT_STRING_SIZE];
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_update_writeformat %s/%d\n", 
-				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt), txframes);
+				ast_getformatname(fmt), txframes);
 	
 	p = find_call(call);
 	if (!p) {
@@ -1426,7 +1429,7 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
 
 	ast_mutex_lock(&p->lock);
 
-	p->writeformat = fmt;
+	ast_format_copy(&p->writeformat, fmt);
 
 	if (p->owner) {
 		while (p->owner && ast_channel_trylock(p->owner)) {
@@ -1440,8 +1443,8 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
 		}
 		if (gH323Debug)
 	  		ast_verbose("Writeformat before update %s/%s\n", 
-			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->writeformat),
-			  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->nativeformats));
+			  ast_getformatname(&p->owner->writeformat),
+			  ast_getformatname_multiple(formats, sizeof(formats), p->owner->nativeformats));
 		if (txframes)
 			ast_codec_pref_setsize(&p->prefs, fmt, txframes);
 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, &p->prefs);
@@ -1454,9 +1457,9 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
 				 p->rtp, p->dtmfcodec, "audio", "cisco-telephone-event", 0);
 		}
 
-		p->owner->nativeformats = fmt;
-	  	ast_set_write_format(p->owner, p->owner->writeformat);
-	  	ast_set_read_format(p->owner, p->owner->readformat);
+		ast_format_cap_set(p->owner->nativeformats, fmt);
+	  	ast_set_write_format(p->owner, &p->owner->writeformat);
+	  	ast_set_read_format(p->owner, &p->owner->readformat);
 		ast_channel_unlock(p->owner);
    	} else
 		ast_log(LOG_ERROR, "No owner found\n");
@@ -1468,14 +1471,13 @@ void ooh323_set_write_format(ooCallData *call, int fmt, int txframes)
 		ast_verbose("+++   ooh323_update_writeformat\n");
 }
 
-void ooh323_set_read_format(ooCallData *call, int fmt)
+void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt)
 {
 	struct ooh323_pvt *p = NULL;
-	char formats[FORMAT_STRING_SIZE];
 
 	if (gH323Debug)
 		ast_verbose("---   ooh323_update_readformat %s\n", 
-				ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, fmt));
+				ast_getformatname(fmt));
 	
 	p = find_call(call);
 	if (!p) {
@@ -1485,8 +1487,7 @@ void ooh323_set_read_format(ooCallData *call, int fmt)
 
 	ast_mutex_lock(&p->lock);
 
-	p->readformat = fmt;
-
+	ast_format_copy(&p->readformat, fmt);
 
 	if (p->owner) {
 		while (p->owner && ast_channel_trylock(p->owner)) {
@@ -1501,9 +1502,9 @@ void ooh323_set_read_format(ooCallData *call, int fmt)
 
 		if (gH323Debug)
 	  		ast_verbose("Readformat before update %s\n", 
-				  ast_getformatname_multiple(formats,FORMAT_STRING_SIZE, p->owner->readformat));
-		p->owner->nativeformats = fmt;
-	  	ast_set_read_format(p->owner, p->owner->readformat);
+				  ast_getformatname(&p->owner->readformat));
+		ast_format_cap_set(p->owner->nativeformats, fmt);
+	  	ast_set_read_format(p->owner, &p->owner->readformat);
 		ast_channel_unlock(p->owner);
    	} else
 		ast_log(LOG_ERROR, "No owner found\n");
@@ -1760,7 +1761,7 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
 		ast_copy_string(p->context, user->context, sizeof(p->context));
 		ast_copy_string(p->accountcode, user->accountcode, sizeof(p->accountcode));
 		p->amaflags = user->amaflags;
-		p->capability = user->capability;
+		ast_format_cap_copy(p->cap, user->cap);
 		memcpy(&p->prefs, &user->prefs, sizeof(struct ast_codec_pref));
 		p->dtmfmode |= user->dtmfmode;
 		p->dtmfcodec = user->dtmfcodec;
@@ -1804,7 +1805,7 @@ int ooh323_onReceivedSetup(ooCallData *call, Q931Message *pmsg)
 	 }
 	}
 
-	ooh323c_set_capability_for_call(call, &p->prefs, p->capability, p->dtmfmode, p->dtmfcodec,
+	ooh323c_set_capability_for_call(call, &p->prefs, p->cap, p->dtmfmode, p->dtmfcodec,
 					 p->t38support);
 	configure_local_rtp(p, call);
 
@@ -1971,7 +1972,7 @@ int onNewCallCreated(ooCallData *call)
 				p->username?p->username:"NULL", call->callToken, prefsBuf);
 		}
 
-      		ooh323c_set_capability_for_call(call, &p->prefs, p->capability, 
+      		ooh323c_set_capability_for_call(call, &p->prefs, p->cap,
                                      p->dtmfmode, p->dtmfcodec, p->t38support);
 
 		configure_local_rtp(p, call);
@@ -2157,6 +2158,7 @@ void ooh323_delete_peer(struct ooh323_peer *peer)
       if(peer->url)      free(peer->url);
       if(peer->e164)     free(peer->e164);
 
+		peer->cap = ast_format_cap_destroy(peer->cap);
 		free(peer);
 	}  
 
@@ -2176,10 +2178,14 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
 
    	user = ast_calloc(1,sizeof(struct ooh323_user));
 	if (user) {
+		if (!(user->cap = ast_format_cap_alloc_nolock())) {
+			ast_free(user);
+			return NULL;
+		}
 		memset(user, 0, sizeof(struct ooh323_user));
 		ast_mutex_init(&user->lock);
 		ast_copy_string(user->name, name, sizeof(user->name));
-		user->capability = gCapability;
+		ast_format_cap_copy(user->cap, gCap);
 		memcpy(&user->prefs, &gPrefs, sizeof(user->prefs));
 		user->rtptimeout = gRTPTimeout;
 		user->dtmfmode = gDTMFMode;
@@ -2223,14 +2229,14 @@ static struct ooh323_user *build_user(const char *name, struct ast_variable *v)
 				} else user->rtpmask = NULL;
 			} else if (!strcasecmp(v->name, "disallow")) {
 				ast_parse_allow_disallow(&user->prefs, 
-					&user->capability,  v->value, 0);
+					user->cap,  v->value, 0);
 			} else if (!strcasecmp(v->name, "allow")) {
 				const char* tcodecs = v->value;
 				if (!strcasecmp(v->value, "all")) {
 					tcodecs = "ulaw,alaw,g729,g723,gsm";
 				}
 				ast_parse_allow_disallow(&user->prefs,
-					 &user->capability,  tcodecs, 1);
+					 user->cap,  tcodecs, 1);
 			} else if (!strcasecmp(v->name, "amaflags")) {
 				user->amaflags = ast_cdr_amaflags2int(v->value);
 			} else if (!strcasecmp(v->name, "ip")) {
@@ -2285,10 +2291,14 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
 
 	peer = ast_calloc(1, sizeof(*peer));
 	if (peer) {
+		if (!(peer->cap = ast_format_cap_alloc_nolock())) {
+			ast_free(peer);
+			return NULL;
+		}
 		memset(peer, 0, sizeof(struct ooh323_peer));
 		ast_mutex_init(&peer->lock);
 		ast_copy_string(peer->name, name, sizeof(peer->name));
-		peer->capability = gCapability;
+		ast_format_cap_copy(peer->cap, gCap);
       		memcpy(&peer->prefs, &gPrefs, sizeof(peer->prefs));
 		peer->rtptimeout = gRTPTimeout;
 		ast_copy_string(peer->accountcode, gAccountcode, sizeof(peer->accountcode));
@@ -2362,14 +2372,14 @@ static struct ooh323_peer *build_peer(const char *name, struct ast_variable *v,
 								sizeof(peer->rtpmaskstr));
 				} else peer->rtpmask = NULL;
 			} else if (!strcasecmp(v->name, "disallow")) {
-				ast_parse_allow_disallow(&peer->prefs, &peer->capability, 
+				ast_parse_allow_disallow(&peer->prefs, peer->cap, 
 												 v->value, 0); 
 			} else if (!strcasecmp(v->name, "allow")) {
 				const char* tcodecs = v->value;
 				if (!strcasecmp(v->value, "all")) {
 					tcodecs = "ulaw,alaw,g729,g723,gsm";
 				}
-				ast_parse_allow_disallow(&peer->prefs, &peer->capability, 
+				ast_parse_allow_disallow(&peer->prefs, peer->cap, 
 												 tcodecs, 1);				 
 			} else if (!strcasecmp(v->name,  "amaflags")) {
 				peer->amaflags = ast_cdr_amaflags2int(v->value);
@@ -2475,6 +2485,7 @@ int reload_config(int reload)
 	struct ooh323_peer *peer = NULL;
 	char *cat;
 	const char *utype;
+	struct ast_format tmpfmt;
 
 	if (gH323Debug)
 		ast_verbose("---   reload_config\n");
@@ -2509,7 +2520,7 @@ int reload_config(int reload)
 	gPort = 1720;
 	gIP[0] = '\0';
 	strcpy(gCallerID, DEFAULT_H323ID);
-   	gCapability = AST_FORMAT_ALAW;
+	ast_format_cap_set(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
 	memset(&gPrefs, 0, sizeof(struct ast_codec_pref));
 	gDTMFMode = H323_DTMF_RFC2833;
 	gDTMFCodec = 101;
@@ -2678,13 +2689,13 @@ int reload_config(int reload)
 		} else if (!strcasecmp(v->name, "accountcode")) {
          ast_copy_string(gAccountcode, v->value, sizeof(gAccountcode));
 		} else if (!strcasecmp(v->name, "disallow")) {
-			ast_parse_allow_disallow(&gPrefs, &gCapability, v->value, 0);
+			ast_parse_allow_disallow(&gPrefs, gCap, v->value, 0);
 		} else if (!strcasecmp(v->name, "allow")) {
 			const char* tcodecs = v->value;
 			if (!strcasecmp(v->value, "all")) {
 				tcodecs = "ulaw,alaw,g729,g723,gsm";
 			}
-			ast_parse_allow_disallow(&gPrefs, &gCapability, tcodecs, 1);
+			ast_parse_allow_disallow(&gPrefs, gCap, tcodecs, 1);
 		} else if (!strcasecmp(v->name, "dtmfmode")) {
 			if (!strcasecmp(v->value, "inband"))
 				gDTMFMode = H323_DTMF_INBAND;
@@ -2893,7 +2904,7 @@ static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, stru
      ast_cli(a->fd, FORMAT, peer->name, 
 					peer->accountcode,
 					ip_port,
-                 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->capability));
+                 ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,peer->cap));
 		prev = peer;
 		peer = peer->next;
 		ast_mutex_unlock(&prev->lock);
@@ -2907,15 +2918,15 @@ static char *handle_cli_ooh323_show_peers(struct ast_cli_entry *e, int cmd, stru
 /*! \brief Print codec list from preference to CLI/manager */
 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
 {
-	int x, codec;
-
+	int x;
+	struct ast_format tmpfmt;
 	for (x = 0; x < 32; x++) {
-		codec = ast_codec_pref_index(pref, x);
-		if (!codec)
+		ast_codec_pref_index(pref, x, &tmpfmt);
+		if (!tmpfmt.id)
 			break;
-		ast_cli(fd, "%s", ast_getformatname(codec));
+		ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
 		ast_cli(fd, ":%d", pref->framing[x]);
-		if (x < 31 && ast_codec_pref_index(pref, x + 1))
+		if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
 			ast_cli(fd, ",");
 	}
 	if (!x)
@@ -3038,7 +3049,7 @@ static char *handle_cli_ooh323_show_users(struct ast_cli_entry *e, int cmd, stru
 		ast_mutex_lock(&user->lock);
      		ast_cli(a->fd, FORMAT1, user->name, 
 					user->accountcode, user->context,
-					ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->capability));
+					ast_getformatname_multiple(formats, FORMAT_STRING_SIZE, user->cap));
 		prev = user;
 		user = user->next;
 		ast_mutex_unlock(&prev->lock);
@@ -3137,7 +3148,7 @@ static char *handle_cli_ooh323_show_config(struct ast_cli_entry *e, int cmd, str
    ast_cli(a->fd,  "%-20s%s\n", "Context:", gContext);
    
    ast_cli(a->fd,  "%-20s%s\n", "Capability:", 
-           ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCapability));
+           ast_getformatname_multiple(value,FORMAT_STRING_SIZE,gCap));
 
    ast_cli(a->fd, "%-20s", "DTMF Mode: ");
 	if (gDTMFMode & H323_DTMF_CISCO) {
@@ -3207,6 +3218,7 @@ static int load_module(void)
 	int res;
 	struct ooAliases * pNewAlias = NULL;
 	struct ooh323_peer *peer = NULL;
+	struct ast_format tmpfmt;
 	OOH225MsgCallbacks h225Callbacks = {0, 0, 0, 0};
 
 	OOH323CALLBACKS h323Callbacks = {
@@ -3221,6 +3233,14 @@ static int load_module(void)
 		.onReceivedDTMF = ooh323_onReceivedDigit,
 		.onModeChanged = onModeChanged
 	};
+	if (!(gCap = ast_format_cap_alloc())) {
+		return 1;
+	}
+	if (!(ooh323_tech.capabilities = ast_format_cap_alloc())) {
+		return 1;
+	}
+	ast_format_cap_add(gCap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add_all(ooh323_tech.capabilities);
 
 	myself = ast_module_info->self;
 
@@ -3334,7 +3354,7 @@ static int load_module(void)
 		ooH323EpSetH323Callbacks(h323Callbacks);
 
 		/* Add endpoint capabilities */
-		if (ooh323c_set_capability(&gPrefs, gCapability, gDTMFMode, gDTMFCodec) < 0) {
+		if (ooh323c_set_capability(&gPrefs, gCap, gDTMFMode, gDTMFCodec) < 0) {
 			ast_log(LOG_ERROR, "Capabilities failure for OOH323. OOH323 Disabled.\n");
 			return 1;
 		}
@@ -3558,7 +3578,7 @@ int ooh323_destroy(struct ooh323_pvt *p)
 
 		ast_mutex_unlock(&cur->lock);
 		ast_mutex_destroy(&cur->lock);
-
+		cur->cap = ast_format_cap_destroy(cur->cap);
 		ast_free(cur);
 	}
 
@@ -3623,6 +3643,7 @@ int delete_users()
 	  			free(prev->rtpmask);
       			}
       		}
+		prev->cap = ast_format_cap_destroy(prev->cap);
 		free(prev);
 		if (cur == userl.users) {
 			break;
@@ -3751,6 +3772,8 @@ static int unload_module(void)
 		ast_verbose("+++ ooh323  unload_module \n");	
 	}
 
+	gCap = ast_format_cap_destroy(gCap);
+	ooh323_tech.capabilities = ast_format_cap_destroy(ooh323_tech.capabilities);
 	return 0;
 }
 
@@ -3802,22 +3825,23 @@ int ooh323_update_capPrefsOrderForCall
 	(ooCallData *call, struct ast_codec_pref *prefs)
 {
 	int i = 0;
-	int codec = ast_codec_pref_index(prefs, i);
+	struct ast_format tmpfmt;
+
+	ast_codec_pref_index(prefs, i, &tmpfmt);
 
 	ooResetCapPrefs(call);
-	while (codec) {
-		ooAppendCapToCapPrefs(call, ooh323_convertAsteriskCapToH323Cap(codec));
-		codec = ast_codec_pref_index(prefs, ++i);
+	while (tmpfmt.id) {
+		ooAppendCapToCapPrefs(call, ooh323_convertAsteriskCapToH323Cap(&tmpfmt));
+		ast_codec_pref_index(prefs, ++i, &tmpfmt);
 	}
 
 	return 0;
 }
 
 
-int ooh323_convertAsteriskCapToH323Cap(format_t cap)
+int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format)
 {
-	char formats[FORMAT_STRING_SIZE];
-	switch (cap) {
+	switch (format->id) {
 	case AST_FORMAT_ULAW:
 		return OO_G711ULAW64K;
 	case AST_FORMAT_ALAW:
@@ -3845,14 +3869,13 @@ int ooh323_convertAsteriskCapToH323Cap(format_t cap)
 	case AST_FORMAT_H263:
 		return OO_H263VIDEO;
 	default:
-		ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", 
-                        ast_getformatname_multiple(formats,FORMAT_STRING_SIZE,cap));
+		ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
 		return -1;
 	}
 }
 
 static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp,
-	 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+	 struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
 {
 	/* XXX Deal with Video */
 	struct ooh323_pvt *p;
@@ -3868,7 +3891,7 @@ static int ooh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
 		return 0;
 	}
 
-	mode = ooh323_convertAsteriskCapToH323Cap(chan->writeformat); 
+	mode = ooh323_convertAsteriskCapToH323Cap(&chan->writeformat); 
 	p = (struct ooh323_pvt *) chan->tech_pvt;
 	if (!p) {
 		ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
@@ -3890,7 +3913,9 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
 	struct ast_sockaddr tmp;
 	ooMediaInfo mediaInfo;
 	int x;
-	format_t format = 0;
+	struct ast_format tmpfmt;
+
+	ast_format_clear(&tmpfmt);
 
 	if (gH323Debug)
 		ast_verbose("---   configure_local_rtp\n");
@@ -3929,9 +3954,9 @@ int configure_local_rtp(struct ooh323_pvt *p, ooCallData *call)
 	ast_copy_string(mediaInfo.lMediaIP, ast_inet_ntoa(us.sin_addr), sizeof(mediaInfo.lMediaIP));
 	mediaInfo.lMediaPort = ntohs(us.sin_port);
 	mediaInfo.lMediaCntrlPort = mediaInfo.lMediaPort +1;
-	for (x = 0; 0 != (format = ast_codec_pref_index(&p->prefs, x)); x++) {
+	for (x = 0; ast_codec_pref_index(&p->prefs, x, &tmpfmt); x++) {
 		strcpy(mediaInfo.dir, "transmit");
-		mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(format);
+		mediaInfo.cap = ooh323_convertAsteriskCapToH323Cap(&tmpfmt);
 		ooAddMediaInfo(call, mediaInfo);
 		strcpy(mediaInfo.dir, "receive");
 		ooAddMediaInfo(call, mediaInfo);
@@ -3995,7 +4020,7 @@ void setup_rtp_connection(ooCallData *call, const char *remoteIp,
 	ast_sockaddr_from_sin(&tmp, &them);
 	ast_rtp_instance_set_remote_address(p->rtp, &tmp);
 
-	if (p->writeformat & AST_FORMAT_G726_AAL2) 
+	if (p->writeformat.id == AST_FORMAT_G726_AAL2) 
                 ast_rtp_codecs_payloads_set_rtpmap_type(ast_rtp_instance_get_codecs(p->rtp), p->rtp, 2,
 							"audio", "G726-32", AST_RTP_OPT_G726_NONSTANDARD);
 
@@ -4237,16 +4262,16 @@ struct ast_frame *ooh323_rtp_read(struct ast_channel *ast, struct ooh323_pvt *p)
 	if (p->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE && !p->faxmode) {
-			if (f->subclass.codec != p->owner->nativeformats) {
-            			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(f->subclass.codec));
-				p->owner->nativeformats = f->subclass.codec;
-				ast_set_read_format(p->owner, p->owner->readformat);
-				ast_set_write_format(p->owner, p->owner->writeformat);
+			if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
+            			ast_debug(1, "Oooh, voice format changed to %s\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_set(p->owner->nativeformats, &f->subclass.format);
+				ast_set_read_format(p->owner, &p->owner->readformat);
+				ast_set_write_format(p->owner, &p->owner->writeformat);
 			}
 
 			if ((p->dtmfmode & H323_DTMF_INBAND) && p->vad &&
-				(f->subclass.codec == AST_FORMAT_SLINEAR || f->subclass.codec == AST_FORMAT_ALAW ||
-					f->subclass.codec == AST_FORMAT_ULAW)) {
+				(f->subclass.format.id == AST_FORMAT_SLINEAR || f->subclass.format.id == AST_FORMAT_ALAW ||
+					f->subclass.format.id == AST_FORMAT_ULAW)) {
 				f = ast_dsp_process(p->owner, p->vad, f);
             			if (f && (f->frametype == AST_FRAME_DTMF)) 
                				ast_debug(1, "* Detected inband DTMF '%c'\n", f->subclass.integer);
diff --git a/addons/chan_ooh323.h b/addons/chan_ooh323.h
index 65eefb7c604fa13418c14f9bce4d6ec34a9894e3..2fb9039175a3cfc8addd19a2fa77de4ec9ebe048 100644
--- a/addons/chan_ooh323.h
+++ b/addons/chan_ooh323.h
@@ -61,7 +61,8 @@
 #include "asterisk/manager.h"
 #include "asterisk/dsp.h"
 #include "asterisk/stringfields.h"
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
 #include "asterisk/udptl.h"
 
 #include "ootypes.h"
@@ -99,13 +100,13 @@ void close_rtp_connection(ooCallData *call);
 struct ast_frame *ooh323_rtp_read
          (struct ast_channel *ast, struct ooh323_pvt *p);
 
-void ooh323_set_write_format(ooCallData *call, int fmt, int txframes);
-void ooh323_set_read_format(ooCallData *call, int fmt);
+void ooh323_set_write_format(ooCallData *call, struct ast_format *fmt, int txframes);
+void ooh323_set_read_format(ooCallData *call, struct ast_format *fmt);
 
 int ooh323_update_capPrefsOrderForCall
    (ooCallData *call, struct ast_codec_pref *prefs);
 
-int ooh323_convertAsteriskCapToH323Cap(format_t cap);
+int ooh323_convertAsteriskCapToH323Cap(struct ast_format *format);
 
 int ooh323_convert_hangupcause_asteriskToH323(int cause);
 int ooh323_convert_hangupcause_h323ToAsterisk(int cause);
diff --git a/addons/format_mp3.c b/addons/format_mp3.c
index ceb1accbbb3311a11b003815d74ec226e9eb2581..d59411d6cbea696b0ebdf57c1a408bf461598368 100644
--- a/addons/format_mp3.c
+++ b/addons/format_mp3.c
@@ -224,7 +224,7 @@ static struct ast_frame *mp3_read(struct ast_filestream *s, int *whennext)
 	p->offset += p->buflen;
 	delay = p->buflen/2;
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, p->buflen);
 	s->fr.mallocd = 0;
 	s->fr.samples = delay;
@@ -293,10 +293,9 @@ static char *mp3_getcomment(struct ast_filestream *s)
 	return NULL;
 }
 
-static const struct ast_format mp3_f = {
+static struct ast_format_def mp3_f = {
 	.name = "mp3",
 	.exts = "mp3",
-	.format = AST_FORMAT_SLINEAR,
 	.open = mp3_open,
 	.write = mp3_write,
 	.rewrite = mp3_rewrite,
@@ -313,13 +312,14 @@ static const struct ast_format mp3_f = {
 
 static int load_module(void)
 {
+	ast_format_set(&mp3_f.format, AST_FORMAT_SLINEAR, 0);
 	InitMP3Constants();
-	return ast_format_register(&mp3_f);
+	return ast_format_def_register(&mp3_f);
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(name);
+	return ast_format_def_unregister(name);
 }	
 
 AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "MP3 format [Any rate but 8000hz mono is optimal]");
diff --git a/addons/ooh323cDriver.c b/addons/ooh323cDriver.c
index dd07bb4b017d240c4e7aa8a68a403c94d468237c..604336c211c747b394b4ba3286a77c5b55c904f1 100644
--- a/addons/ooh323cDriver.c
+++ b/addons/ooh323cDriver.c
@@ -226,15 +226,16 @@ int ooh323c_stop_stack_thread(void)
 }
 
 int ooh323c_set_capability
-   (struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec)
+   (struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec)
 {
-   int ret = 0, x, format=0;
+   int ret = 0, x;
+   struct ast_format tmpfmt;
    if(gH323Debug)
      ast_verbose("\tAdding capabilities to H323 endpoint\n");
    
-   for(x=0; 0 != (format=ast_codec_pref_index(prefs, x)); x++)
+   for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
    {
-      if(format & AST_FORMAT_ULAW)
+      if(tmpfmt.id == AST_FORMAT_ULAW)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g711 ulaw capability to H323 endpoint\n");
@@ -244,7 +245,7 @@ int ooh323c_set_capability
                                      &ooh323c_stop_receive_channel, 
                                      &ooh323c_stop_transmit_channel);
       }
-      if(format & AST_FORMAT_ALAW)
+      if(tmpfmt.id == AST_FORMAT_ALAW)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g711 alaw capability to H323 endpoint\n");
@@ -255,7 +256,7 @@ int ooh323c_set_capability
                                      &ooh323c_stop_transmit_channel);
       }
 
-      if(format & AST_FORMAT_G729A)
+      if(tmpfmt.id == AST_FORMAT_G729A)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g729A capability to H323 endpoint\n");
@@ -281,7 +282,7 @@ int ooh323c_set_capability
                                      &ooh323c_stop_transmit_channel);
       }
 
-      if(format & AST_FORMAT_G723_1)
+      if(tmpfmt.id == AST_FORMAT_G723_1)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g7231 capability to H323 endpoint\n");
@@ -293,7 +294,7 @@ int ooh323c_set_capability
 
       }
 
-      if(format & AST_FORMAT_G726)
+      if(tmpfmt.id == AST_FORMAT_G726)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g726 capability to H323 endpoint\n");
@@ -305,7 +306,7 @@ int ooh323c_set_capability
 
       }
 
-      if(format & AST_FORMAT_G726_AAL2)
+      if(tmpfmt.id == AST_FORMAT_G726_AAL2)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g726aal2 capability to H323 endpoint\n");
@@ -317,7 +318,7 @@ int ooh323c_set_capability
 
       }
 
-      if(format & AST_FORMAT_H263)
+      if(tmpfmt.id == AST_FORMAT_H263)
       {
          if(gH323Debug)
             ast_verbose("\tAdding h263 capability to H323 endpoint\n");
@@ -329,7 +330,7 @@ int ooh323c_set_capability
 
       }
 
-      if(format & AST_FORMAT_GSM)
+      if(tmpfmt.id == AST_FORMAT_GSM)
       {
          if(gH323Debug)
             ast_verbose("\tAdding gsm capability to H323 endpoint\n");
@@ -342,7 +343,7 @@ int ooh323c_set_capability
       }
       
 #ifdef AST_FORMAT_AMRNB
-      if(format & AST_FORMAT_AMRNB)
+      if(tmpfmt.id == AST_FORMAT_AMRNB)
       {
          if(gH323Debug)
             ast_verbose("\tAdding amr nb capability to H323 endpoint\n");
@@ -356,7 +357,7 @@ int ooh323c_set_capability
 #endif
 
 #ifdef AST_FORMAT_SPEEX
-      if(format & AST_FORMAT_SPEEX)
+      if(tmpfmt.id == AST_FORMAT_SPEEX)
       {
          if(gH323Debug)
             ast_verbose("\tAdding speex capability to H323 endpoint\n");
@@ -384,11 +385,11 @@ int ooh323c_set_capability
 }
 
 int ooh323c_set_capability_for_call
-   (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec,
+   (ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
 		 int t38support)
 {
    int ret = 0, x, txframes;
-   int format=0;
+   struct ast_format tmpfmt;
    if(gH323Debug)
      ast_verbose("\tAdding capabilities to call(%s, %s)\n", call->callType, 
                                                             call->callToken);
@@ -409,9 +410,9 @@ int ooh323c_set_capability_for_call
 					&ooh323c_stop_transmit_datachannel,
 					0);
 
-   for(x=0; 0 !=(format=ast_codec_pref_index(prefs, x)); x++)
+   for(x=0; ast_codec_pref_index(prefs, x, &tmpfmt); x++)
    {
-      if(format & AST_FORMAT_ULAW)
+      if(tmpfmt.id == AST_FORMAT_ULAW)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g711 ulaw capability to call(%s, %s)\n", 
@@ -424,7 +425,7 @@ int ooh323c_set_capability_for_call
                                       &ooh323c_stop_receive_channel, 
                                       &ooh323c_stop_transmit_channel);
       }
-      if(format & AST_FORMAT_ALAW)
+      if(tmpfmt.id == AST_FORMAT_ALAW)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g711 alaw capability to call(%s, %s)\n",
@@ -438,7 +439,7 @@ int ooh323c_set_capability_for_call
                                      &ooh323c_stop_transmit_channel);
       }
 
-      if(format & AST_FORMAT_G726)
+      if(tmpfmt.id == AST_FORMAT_G726)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g726 capability to call (%s, %s)\n",
@@ -452,7 +453,7 @@ int ooh323c_set_capability_for_call
 
       }
 
-      if(format & AST_FORMAT_G726_AAL2)
+      if(tmpfmt.id == AST_FORMAT_G726_AAL2)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g726aal2 capability to call (%s, %s)\n",
@@ -466,7 +467,7 @@ int ooh323c_set_capability_for_call
 
       }
 
-      if(format & AST_FORMAT_G729A)
+      if(tmpfmt.id == AST_FORMAT_G729A)
       {
       
          txframes = (prefs->framing[x])/10;
@@ -497,7 +498,7 @@ int ooh323c_set_capability_for_call
 
       }
 
-      if(format & AST_FORMAT_G723_1)
+      if(tmpfmt.id == AST_FORMAT_G723_1)
       {
          if(gH323Debug)
             ast_verbose("\tAdding g7231 capability to call (%s, %s)\n",
@@ -510,7 +511,7 @@ int ooh323c_set_capability_for_call
 
       }
 
-      if(format & AST_FORMAT_H263)
+      if(tmpfmt.id == AST_FORMAT_H263)
       {
          if(gH323Debug)
             ast_verbose("\tAdding h263 capability to call (%s, %s)\n",
@@ -523,7 +524,7 @@ int ooh323c_set_capability_for_call
 
       }
 
-      if(format & AST_FORMAT_GSM)
+      if(tmpfmt.id == AST_FORMAT_GSM)
       {
          if(gH323Debug)
             ast_verbose("\tAdding gsm capability to call(%s, %s)\n", 
@@ -536,7 +537,7 @@ int ooh323c_set_capability_for_call
       }
 
 #ifdef AST_FORMAT_AMRNB
-      if(format & AST_FORMAT_AMRNB)
+      if(tmpfmt.id == AST_FORMAT_AMRNB)
       {
          if(gH323Debug)
             ast_verbose("\tAdding AMR capability to call(%s, %s)\n", 
@@ -549,7 +550,7 @@ int ooh323c_set_capability_for_call
       }
 #endif
 #ifdef AST_FORMAT_SPEEX
-      if(format & AST_FORMAT_SPEEX)
+      if(tmpfmt.id == AST_FORMAT_SPEEX)
       {
          if(gH323Debug)
             ast_verbose("\tAdding Speex capability to call(%s, %s)\n", 
@@ -594,9 +595,9 @@ int ooh323c_set_aliases(ooAliases * aliases)
    
 int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
 {
-   format_t fmt=-1;
-   fmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
-   if(fmt>0) {
+   struct ast_format tmpfmt;
+   convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
+   if(tmpfmt.id) {
       /* ooh323_set_read_format(call, fmt); */
    }else{
      ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
@@ -608,19 +609,19 @@ int ooh323c_start_receive_channel(ooCallData *call, ooLogicalChannel *pChannel)
 
 int ooh323c_start_transmit_channel(ooCallData *call, ooLogicalChannel *pChannel)
 {
-   format_t fmt;
-   fmt = convertH323CapToAsteriskCap(pChannel->chanCap->cap);
-   if(fmt>0) {
-      switch (fmt) {
+   struct ast_format tmpfmt;
+   convertH323CapToAsteriskCap(pChannel->chanCap->cap, &tmpfmt);
+   if(tmpfmt.id) {
+      switch (tmpfmt.id) {
       case AST_FORMAT_ALAW:
       case AST_FORMAT_ULAW:
-	ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
+	ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes);
 	break;
       case AST_FORMAT_G729A:
-	ooh323_set_write_format(call, fmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
+	ooh323_set_write_format(call, &tmpfmt, ((OOCapParams *)(pChannel->chanCap->params))->txframes*10);
 	break;
       default:
-	ooh323_set_write_format(call, fmt, 0);
+	ooh323_set_write_format(call, &tmpfmt, 0);
       }
    }else{
       ast_log(LOG_ERROR, "Invalid capability type for receive channel %s\n",
@@ -665,47 +666,47 @@ int ooh323c_stop_transmit_datachannel(ooCallData *call, ooLogicalChannel *pChann
    return 1;
 }
 
-format_t convertH323CapToAsteriskCap(int cap)
+struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *result)
 {
-
+   ast_format_clear(result);
    switch(cap)
    {
       case OO_G711ULAW64K:
-         return AST_FORMAT_ULAW;
+         return ast_format_set(result, AST_FORMAT_ULAW, 0);
       case OO_G711ALAW64K:
-         return AST_FORMAT_ALAW;
+         return ast_format_set(result, AST_FORMAT_ALAW, 0);
       case OO_GSMFULLRATE:
-         return AST_FORMAT_GSM;
+         return ast_format_set(result, AST_FORMAT_GSM, 0);
 
 #ifdef AST_FORMAT_AMRNB
       case OO_AMRNB:
-         return AST_FORMAT_AMRNB;
+         return ast_format_set(result, AST_FORMAT_AMRNB, 0);
 #endif
 #ifdef AST_FORMAT_SPEEX
       case OO_SPEEX:
-         return AST_FORMAT_SPEEX;
+         return ast_format_set(result, AST_FORMAT_SPEEX, 0);
 #endif
 
       case OO_G729:
-         return AST_FORMAT_G729A;
+         return ast_format_set(result, AST_FORMAT_G729A, 0);
       case OO_G729A:
-         return AST_FORMAT_G729A;
+         return ast_format_set(result, AST_FORMAT_G729A, 0);
       case OO_G729B:
-         return AST_FORMAT_G729A;
+         return ast_format_set(result, AST_FORMAT_G729A, 0);
       case OO_G7231:
-         return AST_FORMAT_G723_1;
+         return ast_format_set(result, AST_FORMAT_G723_1, 0);
       case OO_G726:
-         return AST_FORMAT_G726;
+         return ast_format_set(result, AST_FORMAT_G726, 0);
       case OO_G726AAL2:
-         return AST_FORMAT_G726_AAL2;
+         return ast_format_set(result, AST_FORMAT_G726_AAL2, 0);
       case OO_H263VIDEO:
-         return AST_FORMAT_H263;
+         return ast_format_set(result, AST_FORMAT_H263, 0);
       default:
          ast_debug(1, "Cap %d is not supported by driver yet\n", cap);
-         return -1;
+         return NULL;
    }
 
-   return -1;
+   return NULL;
 }
 
  
diff --git a/addons/ooh323cDriver.h b/addons/ooh323cDriver.h
index 269c56a719c37ce79ca4ecabaf183657c3fa2545..f16b8af2425699c191d8b32dbaa65e62ab084679 100644
--- a/addons/ooh323cDriver.h
+++ b/addons/ooh323cDriver.h
@@ -22,7 +22,7 @@
 #include "ooCalls.h"
 #include "ooCapability.h"
 #include "ooStackCmds.h"
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
 #define H323_DTMF_RFC2833          (1 << 0)
 #define H323_DTMF_Q931             (1 << 1)
 #define H323_DTMF_H245ALPHANUMERIC (1 << 2)
@@ -37,9 +37,9 @@ int ooh323c_stop_stack_thread(void);
 int ooh323c_start_call_thread(ooCallData *call);
 int ooh323c_stop_call_thread(ooCallData *call);
 int ooh323c_set_capability
-   (struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec);
-format_t convertH323CapToAsteriskCap(int cap);
+   (struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec);
+struct ast_format *convertH323CapToAsteriskCap(int cap, struct ast_format *format);
 int ooh323c_set_capability_for_call
-   (ooCallData *call, struct ast_codec_pref *prefs, int capability, int dtmf, int dtmfcodec,
+   (ooCallData *call, struct ast_codec_pref *prefs, struct ast_format_cap *cap, int dtmf, int dtmfcodec,
 	int t38support);
 #endif
diff --git a/apps/app_alarmreceiver.c b/apps/app_alarmreceiver.c
index 952ef722e01ad154840417435688716aeffacd24..6936cb5a0d5ad7bd468c6cb78ff089aaf3054899 100644
--- a/apps/app_alarmreceiver.c
+++ b/apps/app_alarmreceiver.c
@@ -191,7 +191,7 @@ static int send_tone_burst(struct ast_channel *chan, float freq, int duration, i
 
 		if (f->frametype == AST_FRAME_VOICE) {
 			wf.frametype = AST_FRAME_VOICE;
-			wf.subclass.codec = AST_FORMAT_ULAW;
+			ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
 			wf.offset = AST_FRIENDLY_OFFSET;
 			wf.mallocd = 0;
 			wf.data.ptr = tone_block.buf;
@@ -578,12 +578,12 @@ static int alarmreceiver_exec(struct ast_channel *chan, const char *data)
 	/* Set write and read formats to ULAW */
 	ast_verb(4, "AlarmReceiver: Setting read and write formats to ULAW\n");
 
-	if (ast_set_write_format(chan,AST_FORMAT_ULAW)) {
+	if (ast_set_write_format_by_id(chan,AST_FORMAT_ULAW)) {
 		ast_log(LOG_WARNING, "AlarmReceiver: Unable to set write format to Mu-law on %s\n",chan->name);
 		return -1;
 	}
 
-	if (ast_set_read_format(chan,AST_FORMAT_ULAW)) {
+	if (ast_set_read_format_by_id(chan,AST_FORMAT_ULAW)) {
 		ast_log(LOG_WARNING, "AlarmReceiver: Unable to set read format to Mu-law on %s\n",chan->name);
 		return -1;
 	}
diff --git a/apps/app_amd.c b/apps/app_amd.c
index c978ce0f41291643c9d5a41e9bba3cfc2ad93e54..60c13fd956f4c0334c8bc77ebd1e5f076c417dfc 100644
--- a/apps/app_amd.c
+++ b/apps/app_amd.c
@@ -148,7 +148,8 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
 	int res = 0;
 	struct ast_frame *f = NULL;
 	struct ast_dsp *silenceDetector = NULL;
-	int dspsilence = 0, readFormat, framelength = 0;
+	int dspsilence = 0, framelength = 0;
+	struct ast_format readFormat;
 	int inInitialSilence = 1;
 	int inGreeting = 0;
 	int voiceDuration = 0;
@@ -188,10 +189,11 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
 		AST_APP_ARG(argMaximumWordLength);
 	);
 
+	ast_format_clear(&readFormat);
 	ast_verb(3, "AMD: %s %s %s (Fmt: %s)\n", chan->name,
 		S_COR(chan->caller.ani.number.valid, chan->caller.ani.number.str, "(N/A)"),
 		S_COR(chan->redirecting.from.number.valid, chan->redirecting.from.number.str, "(N/A)"),
-		ast_getformatname(chan->readformat));
+		ast_getformatname(&chan->readformat));
 
 	/* Lets parse the arguments. */
 	if (!ast_strlen_zero(parse)) {
@@ -240,8 +242,8 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
 				minimumWordLength, betweenWordsSilence, maximumNumberOfWords, silenceThreshold, maximumWordLength);
 
 	/* Set read format to signed linear so we get signed linear frames in */
-	readFormat = chan->readformat;
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0 ) {
+	ast_format_copy(&readFormat, &chan->readformat);
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0 ) {
 		ast_log(LOG_WARNING, "AMD: Channel [%s]. Unable to set to linear mode, giving up\n", chan->name );
 		pbx_builtin_setvar_helper(chan , "AMDSTATUS", "");
 		pbx_builtin_setvar_helper(chan , "AMDCAUSE", "");
@@ -399,7 +401,7 @@ static void isAnsweringMachine(struct ast_channel *chan, const char *data)
 	pbx_builtin_setvar_helper(chan , "AMDCAUSE" , amdCause);
 
 	/* Restore channel read format */
-	if (readFormat && ast_set_read_format(chan, readFormat))
+	if (readFormat.id && ast_set_read_format(chan, &readFormat))
 		ast_log(LOG_WARNING, "AMD: Unable to restore read format on '%s'\n", chan->name);
 
 	/* Free the DSP used to detect silence */
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 4b671df266bb4764fd30607383a1323069ae9bdb..1fc544afb58390157c9c51fb881c975b0b470845 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -427,6 +427,9 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
 {
 	struct chanspy_translation_helper *csth = data;
 	struct ast_frame *f, *cur;
+	struct ast_format format_slin;
+
+	ast_format_set(&format_slin, AST_FORMAT_SLINEAR, 0);
 
 	ast_audiohook_lock(&csth->spy_audiohook);
 	if (csth->spy_audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
@@ -437,9 +440,9 @@ static int spy_generate(struct ast_channel *chan, void *data, int len, int sampl
 
 	if (ast_test_flag(&csth->spy_audiohook, OPTION_READONLY)) {
 		/* Option 'o' was set, so don't mix channel audio */
-		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, AST_FORMAT_SLINEAR);
+		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_READ, &format_slin);
 	} else {
-		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR);
+		f = ast_audiohook_read_frame(&csth->spy_audiohook, samples, AST_AUDIOHOOK_DIRECTION_BOTH, &format_slin);
 	}
 
 	ast_audiohook_unlock(&csth->spy_audiohook);
@@ -1006,7 +1009,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
 		.volume = '#',
 		.exit = '\0',
 	};
-	int oldwf = 0;
+	struct ast_format oldwf;
 	int volfactor = 0;
 	int res;
 	char *mailbox = NULL;
@@ -1019,6 +1022,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
 	char *parse = ast_strdupa(data);
 
 	AST_STANDARD_APP_ARGS(args, parse);
+	ast_format_clear(&oldwf);
 
 	if (args.spec && !strcmp(args.spec, "all"))
 		args.spec = NULL;
@@ -1082,8 +1086,8 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
 		ast_clear_flag(&flags, AST_FLAGS_ALL);
 	}
 
-	oldwf = chan->writeformat;
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	ast_format_copy(&oldwf, &chan->writeformat);
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 		return -1;
 	}
@@ -1103,7 +1107,7 @@ static int chanspy_exec(struct ast_channel *chan, const char *data)
 	if (fd)
 		close(fd);
 
-	if (oldwf && ast_set_write_format(chan, oldwf) < 0)
+	if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 
 	if (ast_test_flag(&flags, OPTION_EXITONHANGUP)) {
@@ -1125,7 +1129,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
 		.volume = '#',
 		.exit = '\0',
 	};
-	int oldwf = 0;
+	struct ast_format oldwf;
 	int volfactor = 0;
 	int res;
 	char *mailbox = NULL;
@@ -1137,12 +1141,13 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
 	char *parse = ast_strdupa(data);
 
 	AST_STANDARD_APP_ARGS(args, parse);
+	ast_format_clear(&oldwf);
+
 	if (!ast_strlen_zero(args.context) && (ptr = strchr(args.context, '@'))) {
 		exten = args.context;
 		*ptr++ = '\0';
 		args.context = ptr;
 	}
-
 	if (ast_strlen_zero(args.context))
 		args.context = ast_strdupa(chan->context);
 
@@ -1206,7 +1211,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
 	}
 
 	oldwf = chan->writeformat;
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 		return -1;
 	}
@@ -1227,7 +1232,7 @@ static int extenspy_exec(struct ast_channel *chan, const char *data)
 	if (fd)
 		close(fd);
 
-	if (oldwf && ast_set_write_format(chan, oldwf) < 0)
+	if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 
 	return res;
@@ -1242,12 +1247,12 @@ static int dahdiscan_exec(struct ast_channel *chan, const char *data)
 		.volume = '\0',
 		.exit = '*',
 	};
-	int oldwf = 0;
+	struct ast_format oldwf;
 	int res;
 	char *mygroup = NULL;
 
 	ast_clear_flag(&flags, AST_FLAGS_ALL);
-
+	ast_format_clear(&oldwf);
 	if (!ast_strlen_zero(data)) {
 		mygroup = ast_strdupa(data);
 	}
@@ -1255,15 +1260,15 @@ static int dahdiscan_exec(struct ast_channel *chan, const char *data)
 	ast_set_flag(&flags, OPTION_DTMF_CYCLE);
 	ast_set_flag(&flags, OPTION_DAHDI_SCAN);
 
-	oldwf = chan->writeformat;
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	ast_format_copy(&oldwf, &chan->writeformat);
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 		return -1;
 	}
 
 	res = common_exec(chan, &flags, 0, 0, &user_options, mygroup, NULL, spec, NULL, NULL, NULL, NULL);
 
-	if (oldwf && ast_set_write_format(chan, oldwf) < 0)
+	if (oldwf.id && ast_set_write_format(chan, &oldwf) < 0)
 		ast_log(LOG_ERROR, "Could Not Set Write Format.\n");
 
 	return res;
diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c
index 71608d42601584dce71269b3c301140209570113..e533c80e7d322ac9de16100aaa7dc01a2e2c35a6 100644
--- a/apps/app_confbridge.c
+++ b/apps/app_confbridge.c
@@ -568,11 +568,18 @@ static int play_sound_file(struct conference_bridge *conference_bridge, const ch
 
 	if (!(conference_bridge->playback_chan)) {
 		int cause;
-
-		if (!(conference_bridge->playback_chan = ast_request("Bridge", AST_FORMAT_SLINEAR, NULL, "", &cause))) {
+		struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+		struct ast_format tmpfmt;
+		if (!cap) {
+			return -1;
+		}
+		ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+		if (!(conference_bridge->playback_chan = ast_request("Bridge", cap, NULL, "", &cause))) {
 			ast_mutex_unlock(&conference_bridge->playback_lock);
+			cap = ast_format_cap_destroy(cap);
 			return -1;
 		}
+		cap = ast_format_cap_destroy(cap);
 
 		conference_bridge->playback_chan->bridge = conference_bridge->bridge;
 
diff --git a/apps/app_dahdibarge.c b/apps/app_dahdibarge.c
index d9dd59054df07316506c54389956b7f8ba4af57e..082405e80ec7cb502d449116db34491977b9e52e 100644
--- a/apps/app_dahdibarge.c
+++ b/apps/app_dahdibarge.c
@@ -113,13 +113,13 @@ static int conf_run(struct ast_channel *chan, int confno, int confflags)
 	char *buf = __buf + AST_FRIENDLY_OFFSET;
 
 	/* Set it into U-law mode (write) */
-	if (ast_set_write_format(chan, AST_FORMAT_ULAW) < 0) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_ULAW) < 0) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to write ulaw mode\n", chan->name);
 		goto outrun;
 	}
 
 	/* Set it into U-law mode (read) */
-	if (ast_set_read_format(chan, AST_FORMAT_ULAW) < 0) {
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_ULAW) < 0) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to read ulaw mode\n", chan->name);
 		goto outrun;
 	}
@@ -214,11 +214,11 @@ dahdiretry:
 				break;
 			} else if (fd != chan->fds[0]) {
 				if (f->frametype == AST_FRAME_VOICE) {
-					if (f->subclass.codec == AST_FORMAT_ULAW) {
+					if (f->subclass.format.id == AST_FORMAT_ULAW) {
 						/* Carefully write */
 						careful_write(fd, f->data.ptr, f->datalen);
 					} else
-						ast_log(LOG_WARNING, "Huh?  Got a non-ulaw (%s) frame in the conference\n", ast_getformatname(f->subclass.codec));
+						ast_log(LOG_WARNING, "Huh?  Got a non-ulaw (%s) frame in the conference\n", ast_getformatname(&f->subclass.format));
 				}
 			}
 			ast_frfree(f);
@@ -227,7 +227,7 @@ dahdiretry:
 			if (res > 0) {
 				memset(&fr, 0, sizeof(fr));
 				fr.frametype = AST_FRAME_VOICE;
-				fr.subclass.codec = AST_FORMAT_ULAW;
+				ast_format_set(&fr.subclass.format, AST_FORMAT_ULAW, 0);
 				fr.datalen = res;
 				fr.samples = res;
 				fr.data.ptr = buf;
diff --git a/apps/app_dictate.c b/apps/app_dictate.c
index e9e5f0d53d288f60ad5e9ac6fd9e347609187466..5bf439d1609b923fde876b584fd4e022d3d6e0cb 100644
--- a/apps/app_dictate.c
+++ b/apps/app_dictate.c
@@ -97,7 +97,6 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
 	int ffactor = 320 * 80,
 		res = 0,
 		done = 0,
-		oldr = 0,
 		lastop = 0,
 		samples = 0,
 		speed = 1,
@@ -105,6 +104,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
 		len = 0,
 		maxlen = 0,
 		mode = 0;
+	struct ast_format oldr;
+	ast_format_clear(&oldr);
 
 	snprintf(dftbase, sizeof(dftbase), "%s/dictate", ast_config_AST_SPOOL_DIR);
 	if (!ast_strlen_zero(data)) {
@@ -121,8 +122,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
 	if (args.argc > 1 && args.filename) {
 		filename = args.filename;
 	}
-	oldr = chan->readformat;
-	if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
+	ast_format_copy(&oldr, &chan->readformat);
+	if ((res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) < 0) {
 		ast_log(LOG_WARNING, "Unable to set to linear mode.\n");
 		return -1;
 	}
@@ -330,8 +331,8 @@ static int dictate_exec(struct ast_channel *chan, const char *data)
 			ast_frfree(f);
 		}
 	}
-	if (oldr) {
-		ast_set_read_format(chan, oldr);
+	if (oldr.id) {
+		ast_set_read_format(chan, &oldr);
 	}
 	return 0;
 }
diff --git a/apps/app_dumpchan.c b/apps/app_dumpchan.c
index feaeda29e7df646d752877dd247bea9e98a62185..47888935bbfd7692ca631aef53c9de670f1d8afe 100644
--- a/apps/app_dumpchan.c
+++ b/apps/app_dumpchan.c
@@ -126,10 +126,10 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size)
 			c->_state,
 			c->rings,
 			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->nativeformats),
-			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->writeformat),
-			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->readformat),
-			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawwriteformat),
-			ast_getformatname_multiple(formatbuf, sizeof(formatbuf), c->rawreadformat),
+			ast_getformatname(&c->writeformat),
+			ast_getformatname(&c->readformat),
+			ast_getformatname(&c->rawwriteformat),
+			ast_getformatname(&c->rawreadformat),
 			c->fds[0], c->fin & ~DEBUGCHAN_FLAG, (c->fin & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "",
 			c->fout & ~DEBUGCHAN_FLAG, (c->fout & DEBUGCHAN_FLAG) ? " (DEBUGGED)" : "", (long)c->whentohangup.tv_sec,
 			hour,
diff --git a/apps/app_echo.c b/apps/app_echo.c
index 1c721106075b7ffc75a3658c9356cb0e34f6817b..ab991427ddc3c8b5e9f9ccd4430100e8fdede206 100644
--- a/apps/app_echo.c
+++ b/apps/app_echo.c
@@ -51,11 +51,11 @@ static const char app[] = "Echo";
 static int echo_exec(struct ast_channel *chan, const char *data)
 {
 	int res = -1;
-	format_t format;
+	struct ast_format format;
 
-	format = ast_best_codec(chan->nativeformats);
-	ast_set_write_format(chan, format);
-	ast_set_read_format(chan, format);
+	ast_best_codec(chan->nativeformats, &format);
+	ast_set_write_format(chan, &format);
+	ast_set_read_format(chan, &format);
 
 	while (ast_waitfor(chan, -1) > -1) {
 		struct ast_frame *f = ast_read(chan);
diff --git a/apps/app_fax.c b/apps/app_fax.c
index 54d22db1695da46d443e5dfa6e9e0f3ed6b259b3..ce8541910159d859e39c499e29d2ce5657df5d00 100644
--- a/apps/app_fax.c
+++ b/apps/app_fax.c
@@ -329,9 +329,9 @@ static int fax_generator_generate(struct ast_channel *chan, void *data, int len,
     
 	struct ast_frame outf = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.src = __FUNCTION__,
 	};
+	ast_format_set(&outf.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	if (samples > MAX_SAMPLES) {
 		ast_log(LOG_WARNING, "Only generating %d samples, where %d requested\n", MAX_SAMPLES, samples);
@@ -362,8 +362,8 @@ static struct ast_generator generator = {
 static int transmit_audio(fax_session *s)
 {
 	int res = -1;
-	int original_read_fmt = AST_FORMAT_SLINEAR;
-	int original_write_fmt = AST_FORMAT_SLINEAR;
+	struct ast_format original_read_fmt;
+	struct ast_format original_write_fmt;
 	fax_state_t fax;
 	t30_state_t *t30state;
 	struct ast_frame *inf = NULL;
@@ -383,6 +383,9 @@ static int transmit_audio(fax_session *s)
 */
 	};
 
+	ast_format_clear(&original_read_fmt);
+	ast_format_clear(&original_write_fmt);
+
 	/* if in called party mode, try to use T.38 */
 	if (s->caller_mode == FALSE) {
 		/* check if we are already in T.38 mode (unlikely), or if we can request
@@ -455,18 +458,18 @@ static int transmit_audio(fax_session *s)
         t30state = &fax.t30_state;
 #endif
 
-	original_read_fmt = s->chan->readformat;
-	if (original_read_fmt != AST_FORMAT_SLINEAR) {
-		res = ast_set_read_format(s->chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&original_read_fmt, &s->chan->readformat);
+	if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
+		res = ast_set_read_format_by_id(s->chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear read mode, giving up\n");
 			goto done;
 		}
 	}
 
-	original_write_fmt = s->chan->writeformat;
-	if (original_write_fmt != AST_FORMAT_SLINEAR) {
-		res = ast_set_write_format(s->chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&original_write_fmt, &s->chan->writeformat);
+	if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
+		res = ast_set_write_format_by_id(s->chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear write mode, giving up\n");
 			goto done;
@@ -523,12 +526,12 @@ static int transmit_audio(fax_session *s)
 			break;
 		}
 
-		ast_debug(10, "frame %d/%llu, len=%d\n", inf->frametype, (unsigned long long) inf->subclass.codec, inf->datalen);
+		ast_debug(10, "frame %d/%u, len=%d\n", inf->frametype, (unsigned int) inf->subclass.format.id, inf->datalen);
 
 		/* Check the frame type. Format also must be checked because there is a chance
 		   that a frame in old format was already queued before we set channel format
 		   to slinear so it will still be received by ast_read */
-		if (inf->frametype == AST_FRAME_VOICE && inf->subclass.codec == AST_FORMAT_SLINEAR) {
+		if (inf->frametype == AST_FRAME_VOICE && inf->subclass.format.id == AST_FORMAT_SLINEAR) {
 			if (fax_rx(&fax, inf->data.ptr, inf->samples) < 0) {
 				/* I know fax_rx never returns errors. The check here is for good style only */
 				ast_log(LOG_WARNING, "fax_rx returned error\n");
@@ -582,13 +585,13 @@ static int transmit_audio(fax_session *s)
 	fax_release(&fax);
 
 done:
-	if (original_write_fmt != AST_FORMAT_SLINEAR) {
-		if (ast_set_write_format(s->chan, original_write_fmt) < 0)
+	if (original_write_fmt.id != AST_FORMAT_SLINEAR) {
+		if (ast_set_write_format(s->chan, &original_write_fmt) < 0)
 			ast_log(LOG_WARNING, "Unable to restore write format on '%s'\n", s->chan->name);
 	}
 
-	if (original_read_fmt != AST_FORMAT_SLINEAR) {
-		if (ast_set_read_format(s->chan, original_read_fmt) < 0)
+	if (original_read_fmt.id != AST_FORMAT_SLINEAR) {
+		if (ast_set_read_format(s->chan, &original_read_fmt) < 0)
 			ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", s->chan->name);
 	}
 
diff --git a/apps/app_festival.c b/apps/app_festival.c
index ef8827adb1245fb9bdee74cddda2ef5259f7e7c2..f6f3734cac83e276c11efc45a703e8c5ac3f8201 100644
--- a/apps/app_festival.c
+++ b/apps/app_festival.c
@@ -165,7 +165,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
 	int fds[2];
 	int pid = -1;
 	int needed = 0;
-	int owriteformat;
+	struct ast_format owriteformat;
 	struct ast_frame *f;
 	struct myframe {
 		struct ast_frame f;
@@ -175,6 +175,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
 		.f = { 0, },
 	};
 
+	ast_format_clear(&owriteformat);
 	if (pipe(fds)) {
 		ast_log(LOG_WARNING, "Unable to create pipe\n");
 		return -1;
@@ -186,8 +187,8 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
 	ast_stopstream(chan);
 	ast_indicate(chan, -1);
 	
-	owriteformat = chan->writeformat;
-	res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&owriteformat, &chan->writeformat);
+	res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
 	if (res < 0) {
 		ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
 		return -1;
@@ -229,7 +230,7 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
 				res = read(fds[0], myf.frdata, needed);
 				if (res > 0) {
 					myf.f.frametype = AST_FRAME_VOICE;
-					myf.f.subclass.codec = AST_FORMAT_SLINEAR;
+					ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
 					myf.f.datalen = res;
 					myf.f.samples = res / 2;
 					myf.f.offset = AST_FRIENDLY_OFFSET;
@@ -261,8 +262,8 @@ static int send_waveform_to_channel(struct ast_channel *chan, char *waveform, in
 	if (pid > -1)
 		kill(pid, SIGKILL);
 #endif
-	if (!res && owriteformat)
-		ast_set_write_format(chan, owriteformat);
+	if (!res && owriteformat.id)
+		ast_set_write_format(chan, &owriteformat);
 	return res;
 }
 
diff --git a/apps/app_followme.c b/apps/app_followme.c
index 95b1ceafbed5af0049a8d3dc5348e67db9350f46..8b9f1061b998315bc23fbfde4d9c21d59a3859bb 100644
--- a/apps/app_followme.c
+++ b/apps/app_followme.c
@@ -848,7 +848,7 @@ static void findmeexec(struct fm_args *tpargs)
 				return;
 			}
 
-			outbound = ast_request("Local", ast_best_codec(caller->nativeformats), caller, dialarg, &dg);
+			outbound = ast_request("Local", caller->nativeformats, caller, dialarg, &dg);
 			if (outbound) {
 				ast_set_callerid(outbound,
 					S_COR(caller->caller.id.number.valid, caller->caller.id.number.str, NULL),
diff --git a/apps/app_ices.c b/apps/app_ices.c
index f2b9498a6fa8a17e7645c42ec79298aa52f0c9c2..b7eea944cfd584c2df4d475fd5e3c8d7dfc521a2 100644
--- a/apps/app_ices.c
+++ b/apps/app_ices.c
@@ -111,12 +111,13 @@ static int ices_exec(struct ast_channel *chan, const char *data)
 	int ms = -1;
 	int pid = -1;
 	int flags;
-	int oreadformat;
+	struct ast_format oreadformat;
 	struct timeval last;
 	struct ast_frame *f;
 	char filename[256]="";
 	char *c;
 
+	ast_format_clear(&oreadformat);
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "ICES requires an argument (configfile.xml)\n");
 		return -1;
@@ -143,8 +144,8 @@ static int ices_exec(struct ast_channel *chan, const char *data)
 		return -1;
 	}
 
-	oreadformat = chan->readformat;
-	res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&oreadformat, &chan->readformat);
+	res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 	if (res < 0) {
 		close(fds[0]);
 		close(fds[1]);
@@ -195,8 +196,8 @@ static int ices_exec(struct ast_channel *chan, const char *data)
 
 	if (pid > -1)
 		kill(pid, SIGKILL);
-	if (!res && oreadformat)
-		ast_set_read_format(chan, oreadformat);
+	if (!res && oreadformat.id)
+		ast_set_read_format(chan, &oreadformat);
 
 	return res;
 }
diff --git a/apps/app_jack.c b/apps/app_jack.c
index 2f263b6936a060b150a410801c495c2eb872ace3..d073451a8ac1db713bce141815d1240b73a17970 100644
--- a/apps/app_jack.c
+++ b/apps/app_jack.c
@@ -604,12 +604,12 @@ static void handle_jack_audio(struct ast_channel *chan, struct jack_data *jack_d
 	short buf[160];
 	struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.src = "JACK",
 		.data.ptr = buf,
 		.datalen = sizeof(buf),
 		.samples = ARRAY_LEN(buf),
 	};
+	ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	for (;;) {
 		size_t res, read_len;
@@ -754,12 +754,12 @@ static int jack_exec(struct ast_channel *chan, const char *data)
 		return -1;
 	}
 
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		destroy_jack_data(jack_data);
 		return -1;
 	}
 
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		destroy_jack_data(jack_data);
 		return -1;
 	}
@@ -823,9 +823,9 @@ static int jack_hook_callback(struct ast_audiohook *audiohook, struct ast_channe
 	if (frame->frametype != AST_FRAME_VOICE)
 		return 0;
 
-	if (frame->subclass.codec != AST_FORMAT_SLINEAR) {
+	if (frame->subclass.format.id != AST_FORMAT_SLINEAR) {
 		ast_log(LOG_WARNING, "Expected frame in SLINEAR for the audiohook, but got format %s\n",
-			ast_getformatname(frame->subclass.codec));
+			ast_getformatname(&frame->subclass.format));
 		return 0;
 	}
 
diff --git a/apps/app_meetme.c b/apps/app_meetme.c
index 18b1e11003e30be8a79f8f01160f536674e4e971..ae60cfb905e40c8499e94318dde02fa8bbfe5ca9 100644
--- a/apps/app_meetme.c
+++ b/apps/app_meetme.c
@@ -1189,6 +1189,8 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
 	struct ast_conference *cnf;
 	struct dahdi_confinfo dahdic = { 0, };
 	int confno_int = 0;
+	struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
+	struct ast_format tmp_fmt;
 
 	AST_LIST_LOCK(&confs);
 
@@ -1197,9 +1199,10 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
 			break;
 	}
 
-	if (cnf || (!make && !dynamic))
+	if (cnf || (!make && !dynamic) || !cap_slin)
 		goto cnfout;
 
+	ast_format_cap_add(cap_slin, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
 	/* Make a new one */
 	if (!(cnf = ast_calloc(1, sizeof(*cnf))) ||
 		!(cnf->usercontainer = ao2_container_alloc(1, NULL, user_no_cmp))) {
@@ -1245,10 +1248,10 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
 	cnf->dahdiconf = dahdic.confno;
 
 	/* Setup a new channel for playback of audio files */
-	cnf->chan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL);
+	cnf->chan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL);
 	if (cnf->chan) {
-		ast_set_read_format(cnf->chan, AST_FORMAT_SLINEAR);
-		ast_set_write_format(cnf->chan, AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(cnf->chan, AST_FORMAT_SLINEAR);
 		dahdic.chan = 0;
 		dahdic.confno = cnf->dahdiconf;
 		dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@@ -1284,6 +1287,7 @@ static struct ast_conference *build_conf(const char *confno, const char *pin,
 		conf_map[confno_int] = 1;
 	
 cnfout:
+	cap_slin = ast_format_cap_destroy(cap_slin);
 	if (cnf)
 		ast_atomic_fetchadd_int(&cnf->refcount, refcount);
 
@@ -2260,9 +2264,16 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 	int setusercount = 0;
 	int confsilence = 0, totalsilence = 0;
 	char *mailbox, *context;
+	struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
+	struct ast_format tmpfmt;
+
+	if (!cap_slin) {
+		goto conf_run_cleanup;
+	}
+	ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 
 	if (!(user = ao2_alloc(sizeof(*user), NULL))) {
-		return ret;
+		goto conf_run_cleanup;
 	}
 
 	/* Possible timeout waiting for marked user */
@@ -2372,9 +2383,9 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 
 	ast_mutex_lock(&conf->recordthreadlock);
 	if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) &&
-		((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
-		ast_set_read_format(conf->lchan, AST_FORMAT_SLINEAR);
-		ast_set_write_format(conf->lchan, AST_FORMAT_SLINEAR);
+		((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
+		ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
 		dahdic.chan = 0;
 		dahdic.confno = conf->dahdiconf;
 		dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@@ -2601,12 +2612,12 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 		ast_indicate(chan, -1);
 	}
 
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to write linear mode\n", chan->name);
 		goto outrun;
 	}
 
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to read linear mode\n", chan->name);
 		goto outrun;
 	}
@@ -3167,7 +3178,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 					dtmfstr[1] = '\0';
 				}
 
-				if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
+				if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
 					if (user->talk.actual) {
 						ast_frame_adjust_volume(f, user->talk.actual);
 					}
@@ -3339,9 +3350,9 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 									}
 
 									ast_mutex_lock(&conf->recordthreadlock);
-									if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, chan, "pseudo", NULL)))) {
-										ast_set_read_format(conf->lchan, AST_FORMAT_SLINEAR);
-										ast_set_write_format(conf->lchan, AST_FORMAT_SLINEAR);
+									if ((conf->recordthread == AST_PTHREADT_NULL) && ast_test_flag64(confflags, CONFFLAG_RECORDCONF) && ((conf->lchan = ast_request("DAHDI", cap_slin, chan, "pseudo", NULL)))) {
+										ast_set_read_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
+										ast_set_write_format_by_id(conf->lchan, AST_FORMAT_SLINEAR);
 										dahdic.chan = 0;
 										dahdic.confno = conf->dahdiconf;
 										dahdic.confmode = DAHDI_CONF_CONFANN | DAHDI_CONF_CONFANNMON;
@@ -3627,7 +3638,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 				if (res > 0) {
 					memset(&fr, 0, sizeof(fr));
 					fr.frametype = AST_FRAME_VOICE;
-					fr.subclass.codec = AST_FORMAT_SLINEAR;
+					ast_format_set(&fr.subclass.format, AST_FORMAT_SLINEAR, 0);
 					fr.datalen = res;
 					fr.samples = res / 2;
 					fr.data.ptr = buf;
@@ -3639,7 +3650,7 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 						 )) {
 						int idx;
 						for (idx = 0; idx < AST_FRAME_BITS; idx++) {
-							if (chan->rawwriteformat & (1 << idx)) {
+							if (ast_format_to_old_bitfield(&chan->rawwriteformat) & (1 << idx)) {
 								break;
 							}
 						}
@@ -3654,7 +3665,11 @@ static int conf_run(struct ast_channel *chan, struct ast_conference *conf, struc
 									mohtempstopped = 1;
 								}
 								if (!conf->transpath[idx]) {
-									conf->transpath[idx] = ast_translator_build_path((1 << idx), AST_FORMAT_SLINEAR);
+									struct ast_format src;
+									struct ast_format dst;
+									ast_format_set(&src, AST_FORMAT_SLINEAR, 0);
+									ast_format_from_old_bitfield(&dst, (1 << idx));
+									conf->transpath[idx] = ast_translator_build_path(&dst, &src);
 								}
 								if (conf->transpath[idx]) {
 									conf->transframe[idx] = ast_translate(conf->transpath[idx], conf->origframe, 0);
@@ -3821,6 +3836,10 @@ bailoutandtrynormal:
 	ao2_ref(user, -1);
 	AST_LIST_UNLOCK(&confs);
 
+
+conf_run_cleanup:
+	cap_slin = ast_format_cap_destroy(cap_slin);
+
 	return ret;
 }
 
diff --git a/apps/app_milliwatt.c b/apps/app_milliwatt.c
index 24137606d3191eb116432978e60914fa3a327fd0..26cba3c40f0e101c8b3f580015b8cc3e22c15afd 100644
--- a/apps/app_milliwatt.c
+++ b/apps/app_milliwatt.c
@@ -78,10 +78,10 @@ static int milliwatt_generate(struct ast_channel *chan, void *data, int len, int
 	int i, *indexp = (int *) data;
 	struct ast_frame wf = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_ULAW,
 		.offset = AST_FRIENDLY_OFFSET,
 		.src = __FUNCTION__,
 	};
+	ast_format_set(&wf.subclass.format, AST_FORMAT_ULAW, 0);
 	wf.data.ptr = buf + AST_FRIENDLY_OFFSET;
 
 	/* Instead of len, use samples, because channel.c generator_force
@@ -120,8 +120,8 @@ static struct ast_generator milliwattgen = {
 
 static int old_milliwatt_exec(struct ast_channel *chan)
 {
-	ast_set_write_format(chan, AST_FORMAT_ULAW);
-	ast_set_read_format(chan, AST_FORMAT_ULAW);
+	ast_set_write_format_by_id(chan, AST_FORMAT_ULAW);
+	ast_set_read_format_by_id(chan, AST_FORMAT_ULAW);
 
 	if (chan->_state != AST_STATE_UP) {
 		ast_answer(chan);
diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c
index ca3a23991b8ad05b63f4946bef73e0946ea084cf..8e6adead194757f6565e2dd0c05788177f745978 100644
--- a/apps/app_mixmonitor.c
+++ b/apps/app_mixmonitor.c
@@ -281,7 +281,9 @@ static void *mixmonitor_thread(void *obj)
 	unsigned int oflags;
 	char *ext;
 	int errflag = 0;
+	struct ast_format format_slin;
 
+	ast_format_set(&format_slin, AST_FORMAT_SLINEAR, 0);
 	ast_verb(2, "Begin MixMonitor Recording %s\n", mixmonitor->name);
 
 	fs = &mixmonitor->mixmonitor_ds->fs;
@@ -291,7 +293,7 @@ static void *mixmonitor_thread(void *obj)
 	while (mixmonitor->audiohook.status == AST_AUDIOHOOK_STATUS_RUNNING && !mixmonitor->mixmonitor_ds->fs_quit) {
 		struct ast_frame *fr = NULL;
 
-		if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, AST_FORMAT_SLINEAR))) {
+		if (!(fr = ast_audiohook_read_frame(&mixmonitor->audiohook, SAMPLES_PER_FRAME, AST_AUDIOHOOK_DIRECTION_BOTH, &format_slin))) {
 			ast_audiohook_trigger_wait(&mixmonitor->audiohook);
 
 			if (mixmonitor->audiohook.status != AST_AUDIOHOOK_STATUS_RUNNING) {
diff --git a/apps/app_mp3.c b/apps/app_mp3.c
index f8e42a12c75a0a5d9bc23f026fb8340f67934bfc..f8c5a05781f98b8230d30461c29269ac78a02390 100644
--- a/apps/app_mp3.c
+++ b/apps/app_mp3.c
@@ -137,7 +137,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
 	int fds[2];
 	int ms = -1;
 	int pid = -1;
-	int owriteformat;
+	struct ast_format owriteformat;
 	int timeout = 2000;
 	struct timeval next;
 	struct ast_frame *f;
@@ -149,6 +149,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
 		.f = { 0, },
 	};
 
+	ast_format_clear(&owriteformat);
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "MP3 Playback requires an argument (filename)\n");
 		return -1;
@@ -161,8 +162,8 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
 	
 	ast_stopstream(chan);
 
-	owriteformat = chan->writeformat;
-	res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&owriteformat, &chan->writeformat);
+	res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
 	if (res < 0) {
 		ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
 		return -1;
@@ -185,7 +186,7 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
 				res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata), timeout);
 				if (res > 0) {
 					myf.f.frametype = AST_FRAME_VOICE;
-					myf.f.subclass.codec = AST_FORMAT_SLINEAR;
+					ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
 					myf.f.datalen = res;
 					myf.f.samples = res / 2;
 					myf.f.mallocd = 0;
@@ -234,8 +235,8 @@ static int mp3_exec(struct ast_channel *chan, const char *data)
 	
 	if (pid > -1)
 		kill(pid, SIGKILL);
-	if (!res && owriteformat)
-		ast_set_write_format(chan, owriteformat);
+	if (!res && owriteformat.id)
+		ast_set_write_format(chan, &owriteformat);
 	
 	return res;
 }
diff --git a/apps/app_nbscat.c b/apps/app_nbscat.c
index dd7637a83b763bfd0a716c444035ac0e3ffdda45..2bbde630e1060879e1d207a54370c521b5becb05 100644
--- a/apps/app_nbscat.c
+++ b/apps/app_nbscat.c
@@ -111,7 +111,7 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
 	int fds[2];
 	int ms = -1;
 	int pid = -1;
-	int owriteformat;
+	struct ast_format owriteformat;
 	struct timeval next;
 	struct ast_frame *f;
 	struct myframe {
@@ -119,7 +119,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
 		char offset[AST_FRIENDLY_OFFSET];
 		short frdata[160];
 	} myf;
-	
+
+	ast_format_clear(&owriteformat);
 	if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds)) {
 		ast_log(LOG_WARNING, "Unable to create socketpair\n");
 		return -1;
@@ -127,8 +128,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
 	
 	ast_stopstream(chan);
 
-	owriteformat = chan->writeformat;
-	res = ast_set_write_format(chan, AST_FORMAT_SLINEAR);
+	ast_format_copy(&owriteformat, &chan->writeformat);
+	res = ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
 	if (res < 0) {
 		ast_log(LOG_WARNING, "Unable to set write format to signed linear\n");
 		return -1;
@@ -148,7 +149,7 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
 				res = timed_read(fds[0], myf.frdata, sizeof(myf.frdata));
 				if (res > 0) {
 					myf.f.frametype = AST_FRAME_VOICE;
-					myf.f.subclass.codec = AST_FORMAT_SLINEAR;
+					ast_format_set(&myf.f.subclass.format, AST_FORMAT_SLINEAR, 0);
 					myf.f.datalen = res;
 					myf.f.samples = res / 2;
 					myf.f.mallocd = 0;
@@ -197,8 +198,8 @@ static int NBScat_exec(struct ast_channel *chan, const char *data)
 	
 	if (pid > -1)
 		kill(pid, SIGKILL);
-	if (!res && owriteformat)
-		ast_set_write_format(chan, owriteformat);
+	if (!res && owriteformat.id)
+		ast_set_write_format(chan, &owriteformat);
 
 	return res;
 }
diff --git a/apps/app_originate.c b/apps/app_originate.c
index 659ea2949f02c05bb0bb72972b520497ce112a44..94ac3596cdb45539f2808ce3d888d5867fdc176d 100644
--- a/apps/app_originate.c
+++ b/apps/app_originate.c
@@ -105,8 +105,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
 	int outgoing_status = 0;
 	static const unsigned int timeout = 30;
 	static const char default_exten[] = "s";
+	struct ast_format tmpfmt;
+	struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
 
 	ast_autoservice_start(chan);
+	if (!cap_slin) {
+		goto return_cleanup;
+	}
+	ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_ERROR, "Originate() requires arguments\n");
@@ -148,14 +154,14 @@ static int originate_exec(struct ast_channel *chan, const char *data)
 		ast_debug(1, "Originating call to '%s/%s' and connecting them to extension %s,%s,%d\n",
 				chantech, chandata, args.arg1, exten, priority);
 
-		outgoing_res = ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata,
+		outgoing_res = ast_pbx_outgoing_exten(chantech, cap_slin, chandata,
 				timeout * 1000, args.arg1, exten, priority, &outgoing_status, 0, NULL,
 				NULL, NULL, NULL, NULL);
 	} else if (!strcasecmp(args.type, "app")) {
 		ast_debug(1, "Originating call to '%s/%s' and connecting them to %s(%s)\n",
 				chantech, chandata, args.arg1, S_OR(args.arg2, ""));
 
-		outgoing_res = ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata,
+		outgoing_res = ast_pbx_outgoing_app(chantech, cap_slin, chandata,
 				timeout * 1000, args.arg1, args.arg2, &outgoing_status, 0, NULL,
 				NULL, NULL, NULL, NULL);
 	} else {
@@ -194,7 +200,7 @@ return_cleanup:
 			break;
 		}
 	}
-
+	cap_slin = ast_format_cap_destroy(cap_slin);
 	ast_autoservice_stop(chan);
 
 	return res;
diff --git a/apps/app_parkandannounce.c b/apps/app_parkandannounce.c
index 5bb8b659465dc3164c727c47480a0681ed2e546f..fb3e713e13bd558c8e75e46470ebd691678cc495 100644
--- a/apps/app_parkandannounce.c
+++ b/apps/app_parkandannounce.c
@@ -96,6 +96,9 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 	struct ast_channel *dchan;
 	struct outgoing_helper oh = { 0, };
 	int outstate;
+	struct ast_format tmpfmt;
+	struct ast_format_cap *cap_slin = ast_format_cap_alloc_nolock();
+
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(template);
 		AST_APP_ARG(timeout);
@@ -104,9 +107,15 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 	);
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "ParkAndAnnounce requires arguments: (announce:template|timeout|dial|[return_context])\n");
-		return -1;
+		res = -1;
+		goto parkcleanup;
+	}
+	if (!cap_slin) {
+		res = -1;
+		goto parkcleanup;
 	}
-  
+	ast_format_cap_add(cap_slin, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+
 	s = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, s);
 
@@ -115,7 +124,8 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 
 	if (ast_strlen_zero(args.dial)) {
 		ast_log(LOG_WARNING, "PARK: A dial resource must be specified i.e: Console/dsp or DAHDI/g1/5551212\n");
-		return -1;
+		res = -1;
+		goto parkcleanup;
 	}
 
 	dialtech = strsep(&args.dial, "/");
@@ -138,8 +148,9 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 	before we are done announcing and the channel is messed with, Kablooeee.  So we use Masq to prevent this.  */
 
 	res = ast_masq_park_call(chan, NULL, timeout, &lot);
-	if (res == -1)
-		return res;
+	if (res == -1) {
+		goto parkcleanup;
+	}
 
 	ast_verb(3, "Call Parking Called, lot: %d, timeout: %d, context: %s\n", lot, timeout, args.return_context);
 
@@ -148,7 +159,7 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 	snprintf(buf, sizeof(buf), "%d", lot);
 	oh.parent_channel = chan;
 	oh.vars = ast_variable_new("_PARKEDAT", buf, "");
-	dchan = __ast_request_and_dial(dialtech, AST_FORMAT_SLINEAR, chan, args.dial, 30000,
+	dchan = __ast_request_and_dial(dialtech, cap_slin, chan, args.dial, 30000,
 		&outstate,
 		S_COR(chan->caller.id.number.valid, chan->caller.id.number.str, NULL),
 		S_COR(chan->caller.id.name.valid, chan->caller.id.name.str, NULL),
@@ -160,11 +171,13 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 			ast_verb(4, "Channel %s was never answered.\n", dchan->name);
 			ast_log(LOG_WARNING, "PARK: Channel %s was never answered for the announce.\n", dchan->name);
 			ast_hangup(dchan);
-			return -1;
+			res = -1;
+			goto parkcleanup;
 		}
 	} else {
 		ast_log(LOG_WARNING, "PARK: Unable to allocate announce channel.\n");
-		return -1; 
+		res = -1;
+		goto parkcleanup;
 	}
 
 	ast_stopstream(dchan);
@@ -197,7 +210,10 @@ static int parkandannounce_exec(struct ast_channel *chan, const char *data)
 
 	ast_stopstream(dchan);  
 	ast_hangup(dchan);
-	
+
+parkcleanup:
+	cap_slin = ast_format_cap_destroy(cap_slin);
+
 	return res;
 }
 
diff --git a/apps/app_record.c b/apps/app_record.c
index 64e635018b6e9a1d5328eb3b7b08baca0e52491f..a192b1adc1fd46191b6fb7bab64c0d8022f864e7 100644
--- a/apps/app_record.c
+++ b/apps/app_record.c
@@ -154,7 +154,7 @@ static int record_exec(struct ast_channel *chan, const char *data)
 	int maxduration = 0;		/* max duration of recording in milliseconds */
 	int gottimeout = 0;		/* did we timeout for maxduration exceeded? */
 	int terminator = '#';
-	int rfmt = 0;
+	struct ast_format rfmt;
 	int ioflags;
 	int waitres;
 	struct ast_silence_generator *silgen = NULL;
@@ -165,7 +165,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
 		AST_APP_ARG(maxduration);
 		AST_APP_ARG(options);
 	);
-	
+
+	ast_format_clear(&rfmt);
 	/* The next few lines of code parse out the filename and header from the input string */
 	if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */
 		ast_log(LOG_WARNING, "Record requires an argument (filename)\n");
@@ -286,8 +287,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
 	/* The end of beep code.  Now the recording starts */
 
 	if (silence > 0) {
-		rfmt = chan->readformat;
-		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		ast_format_copy(&rfmt, &chan->readformat);
+		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
 			pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR");
@@ -408,8 +409,8 @@ static int record_exec(struct ast_channel *chan, const char *data)
 		ast_channel_stop_silence_generator(chan, silgen);
 
 out:
-	if ((silence > 0) && rfmt) {
-		res = ast_set_read_format(chan, rfmt);
+	if ((silence > 0) && rfmt.id) {
+		res = ast_set_read_format(chan, &rfmt);
 		if (res)
 			ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
 		if (sildet)
diff --git a/apps/app_rpt.c b/apps/app_rpt.c
index a4d350d32eb3286977055e104d3499578048b421..765f73184b8714162e478256b071af78920cade7 100644
--- a/apps/app_rpt.c
+++ b/apps/app_rpt.c
@@ -882,6 +882,7 @@ static int setrem(struct rpt *myrpt);
 static int setrtx_check(struct rpt *myrpt);
 static int channel_revert(struct rpt *myrpt);
 static int channel_steer(struct rpt *myrpt, char *data);
+static struct ast_format_cap *get_slin_cap(struct ast_format_cap *cap);
 
 AST_MUTEX_DEFINE_STATIC(nodeloglock);
 
@@ -951,7 +952,6 @@ int	i;
 	return(NULL);
 }
 
-
 static void rpt_mutex_spew(void)
 {
 	struct by_lightning lock_ring_copy[32];
@@ -1070,6 +1070,18 @@ pthread_t id;
 
 #endif  /* APP_RPT_LOCK_DEBUG */
 
+static struct ast_format_cap *get_slin_cap(struct ast_format_cap *cap)
+{
+	struct ast_format tmp;
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
+		return NULL;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
+
+	return cap;
+}
+
 /*
 * Return 1 if rig is multimode capable
 */
@@ -3961,7 +3973,7 @@ char mhz[MAXREMSTR];
 char decimals[MAXREMSTR];
 char	mystr[200];
 struct dahdi_params par;
-
+struct ast_format_cap *cap = NULL;
 
 	/* get a pointer to myrpt */
 	myrpt = mytele->rpt;
@@ -4004,7 +4016,8 @@ struct dahdi_params par;
 
 
 	/* allocate a pseudo-channel thru asterisk */
-	mychannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	mychannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!mychannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -5288,10 +5301,12 @@ struct	rpt *myrpt = (struct rpt *)this;
 int	res;
 int stopped,congstarted,dialtimer,lastcidx,aborted;
 struct ast_channel *mychannel,*genchannel;
+struct ast_format_cap *cap = NULL;
 
 	myrpt->mydtmf = 0;
 	/* allocate a pseudo-channel thru asterisk */
-	mychannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	mychannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!mychannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -5317,7 +5332,8 @@ struct ast_channel *mychannel,*genchannel;
 		pthread_exit(NULL);
 	}
 	/* allocate a pseudo-channel thru asterisk */
-	genchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	genchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!genchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -5689,6 +5705,7 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
 	int reconnects = 0;
 	int i,n;
 	struct dahdi_confinfo ci;  /* conference info */
+	struct ast_format_cap *cap = NULL;
 
 	val = node_lookup(myrpt,node);
 	if (!val){
@@ -5792,10 +5809,11 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
 		return -1;
 	}
 	*tele++ = 0;
-	l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+	l->chan = ast_request(deststr, get_slin_cap(cap), NULL, tele, NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (l->chan){
-		ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
-		ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(l->chan, AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(l->chan, AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 		if (l->chan->cdr)
 			ast_set_flag(l->chan->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -5827,15 +5845,16 @@ static int connect_link(struct rpt *myrpt, char* node, int mode, int perma)
 		return -1;
 	}
 	/* allocate a pseudo-channel thru asterisk */
-	l->pchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	l->pchan = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!l->pchan){
 		ast_log(LOG_WARNING,"rpt connect: Sorry unable to obtain pseudo channel\n");
 		ast_hangup(l->chan);
 		ast_free(l);
 		return -1;
 	}
-	ast_set_read_format(l->pchan, AST_FORMAT_SLINEAR);
-	ast_set_write_format(l->pchan, AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(l->pchan, AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(l->pchan, AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 	if (l->pchan->cdr)
 		ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -10341,6 +10360,7 @@ static int attempt_reconnect(struct rpt *myrpt, struct rpt_link *l)
 	char *val, *s, *s1, *s2, *tele;
 	char tmp[300], deststr[300] = "";
 	char sx[320],*sy;
+	struct ast_format_cap *cap = NULL;
 
 
 	val = node_lookup(myrpt,l->name);
@@ -10376,10 +10396,11 @@ static int attempt_reconnect(struct rpt *myrpt, struct rpt_link *l)
 	l->connecttime = 0;
 	l->thisconnected = 0;
 	l->newkey = 0;
-	l->chan = ast_request(deststr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+	l->chan = ast_request(deststr, get_slin_cap(cap), NULL, tele, NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (l->chan){
-		ast_set_read_format(l->chan, AST_FORMAT_SLINEAR);
-		ast_set_write_format(l->chan, AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(l->chan, AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(l->chan, AST_FORMAT_SLINEAR);
 #ifndef	NEW_ASTERISK
 		l->chan->whentohangup = 0;
 #endif
@@ -10743,6 +10764,7 @@ time_t	t;
 struct rpt_link *l,*m;
 struct rpt_tele *telem;
 char tmpstr[300],lstr[MAXLINKLIST];
+struct ast_format_cap *cap = NULL;
 
 
 	if (myrpt->p.archivedir) mkdir(myrpt->p.archivedir,0600);
@@ -10795,7 +10817,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 		pthread_exit(NULL);
 	}
 	*tele++ = 0;
-	myrpt->rxchannel = ast_request(tmpstr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+	myrpt->rxchannel = ast_request(tmpstr, get_slin_cap(cap), NULL, tele, NULL);
+	cap = ast_format_cap_destroy(cap);
 	myrpt->dahdirxchannel = NULL;
 	if (!strcasecmp(tmpstr,"DAHDI"))
 		myrpt->dahdirxchannel = myrpt->rxchannel;
@@ -10809,8 +10832,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 			myrpt->rpt_thread = AST_PTHREADT_STOP;
 			pthread_exit(NULL);
 		}
-		ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
-		ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 		if (myrpt->rxchannel->cdr)
 			ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -10853,7 +10876,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 			pthread_exit(NULL);
 		}
 		*tele++ = 0;
-		myrpt->txchannel = ast_request(tmpstr, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+		myrpt->txchannel = ast_request(tmpstr, get_slin_cap(cap), NULL, tele, NULL);
+		cap = ast_format_cap_destroy(cap);
 		if (!strcasecmp(tmpstr,"DAHDI"))
 			myrpt->dahditxchannel = myrpt->txchannel;
 		if (myrpt->txchannel)
@@ -10867,8 +10891,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 				myrpt->rpt_thread = AST_PTHREADT_STOP;
 				pthread_exit(NULL);
 			}			
-			ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
-			ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
+			ast_set_read_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
+			ast_set_write_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 			if (myrpt->txchannel->cdr)
 				ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -10909,7 +10933,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 	ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_KEY);
 	ast_indicate(myrpt->txchannel,AST_CONTROL_RADIO_UNKEY);
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->pchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->pchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->pchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -10928,7 +10953,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 	if (!myrpt->dahditxchannel)
 	{
 		/* allocate a pseudo-channel thru asterisk */
-		myrpt->dahditxchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+		myrpt->dahditxchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+		cap = ast_format_cap_destroy(cap);
 		if (!myrpt->dahditxchannel)
 		{
 			fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -10939,15 +10965,16 @@ char tmpstr[300],lstr[MAXLINKLIST];
 			myrpt->rpt_thread = AST_PTHREADT_STOP;
 			pthread_exit(NULL);
 		}
-		ast_set_read_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
-		ast_set_write_format(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(myrpt->dahditxchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 		if (myrpt->dahditxchannel->cdr)
 			ast_set_flag(myrpt->dahditxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
 #endif
 	}
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->monchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->monchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->monchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -10958,8 +10985,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 		myrpt->rpt_thread = AST_PTHREADT_STOP;
 		pthread_exit(NULL);
 	}
-	ast_set_read_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
-	ast_set_write_format(myrpt->monchannel,AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(myrpt->monchannel,AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(myrpt->monchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 	if (myrpt->monchannel->cdr)
 		ast_set_flag(myrpt->monchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -11042,7 +11069,8 @@ char tmpstr[300],lstr[MAXLINKLIST];
 		pthread_exit(NULL);
 	}
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->parrotchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->parrotchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->parrotchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -11053,14 +11081,15 @@ char tmpstr[300],lstr[MAXLINKLIST];
 		myrpt->rpt_thread = AST_PTHREADT_STOP;
 		pthread_exit(NULL);
 	}
-	ast_set_read_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
-	ast_set_write_format(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(myrpt->parrotchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 	if (myrpt->parrotchannel->cdr)
 		ast_set_flag(myrpt->parrotchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
 #endif
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->voxchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->voxchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->voxchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -11071,14 +11100,15 @@ char tmpstr[300],lstr[MAXLINKLIST];
 		myrpt->rpt_thread = AST_PTHREADT_STOP;
 		pthread_exit(NULL);
 	}
-	ast_set_read_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
-	ast_set_write_format(myrpt->voxchannel,AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(myrpt->voxchannel,AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(myrpt->voxchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 	if (myrpt->voxchannel->cdr)
 		ast_set_flag(myrpt->voxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
 #endif
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->txpchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->txpchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->txpchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -13146,6 +13176,7 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 	struct	dahdi_radio_param z;
 	struct rpt_tele *telem;
 	int	numlinks;
+	struct ast_format_cap *cap = NULL;
 
 	nullfd = open("/dev/null",O_RDWR);
 	if (ast_strlen_zero(data)) {
@@ -13631,17 +13662,18 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 		l->lastf2 = NULL;
 		l->dtmfed = 0;
 		voxinit_link(l,1);
-		ast_set_read_format(l->chan,AST_FORMAT_SLINEAR);
-		ast_set_write_format(l->chan,AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(l->chan,AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(l->chan,AST_FORMAT_SLINEAR);
 		/* allocate a pseudo-channel thru asterisk */
-		l->pchan = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+		l->pchan = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+		cap = ast_format_cap_destroy(cap);
 		if (!l->pchan)
 		{
 			fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
 			pthread_exit(NULL);
 		}
-		ast_set_read_format(l->pchan,AST_FORMAT_SLINEAR);
-		ast_set_write_format(l->pchan,AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(l->pchan,AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(l->pchan,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 		if (l->pchan->cdr)
 			ast_set_flag(l->pchan->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -13778,14 +13810,15 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 		pthread_exit(NULL);
 	}
 	*tele++ = 0;
-	myrpt->rxchannel = ast_request(myrpt->rxchanname, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+	myrpt->rxchannel = ast_request(myrpt->rxchanname, get_slin_cap(cap), NULL, tele, NULL);
+	cap = ast_format_cap_destroy(cap);
 	myrpt->dahdirxchannel = NULL;
 	if (!strcasecmp(myrpt->rxchanname,"DAHDI"))
 		myrpt->dahdirxchannel = myrpt->rxchannel;
 	if (myrpt->rxchannel)
 	{
-		ast_set_read_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
-		ast_set_write_format(myrpt->rxchannel,AST_FORMAT_SLINEAR);
+		ast_set_read_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
+		ast_set_write_format_by_id(myrpt->rxchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 		if (myrpt->rxchannel->cdr)
 			ast_set_flag(myrpt->rxchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -13821,13 +13854,14 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 			pthread_exit(NULL);
 		}
 		*tele++ = 0;
-		myrpt->txchannel = ast_request(myrpt->txchanname, AST_FORMAT_SLINEAR, NULL, tele, NULL);
+		myrpt->txchannel = ast_request(myrpt->txchanname, get_slin_cap(cap), NULL, tele, NULL);
+		cap = ast_format_cap_destroy(cap);
 		if (!strncasecmp(myrpt->txchanname,"DAHDI",3))
 			myrpt->dahditxchannel = myrpt->txchannel;
 		if (myrpt->txchannel)
 		{
-			ast_set_read_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
-			ast_set_write_format(myrpt->txchannel,AST_FORMAT_SLINEAR);
+			ast_set_read_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
+			ast_set_write_format_by_id(myrpt->txchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 			if (myrpt->txchannel->cdr)
 				ast_set_flag(myrpt->txchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -13860,7 +13894,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 			myrpt->dahditxchannel = myrpt->rxchannel;
 	}
 	/* allocate a pseudo-channel thru asterisk */
-	myrpt->pchannel = ast_request("DAHDI", AST_FORMAT_SLINEAR, NULL, "pseudo", NULL);
+	myrpt->pchannel = ast_request("DAHDI", get_slin_cap(cap), NULL, "pseudo", NULL);
+	cap = ast_format_cap_destroy(cap);
 	if (!myrpt->pchannel)
 	{
 		fprintf(stderr,"rpt:Sorry unable to obtain pseudo channel\n");
@@ -13870,8 +13905,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 		ast_hangup(myrpt->rxchannel);
 		pthread_exit(NULL);
 	}
-	ast_set_read_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
-	ast_set_write_format(myrpt->pchannel,AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(myrpt->pchannel,AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(myrpt->pchannel,AST_FORMAT_SLINEAR);
 #ifdef	AST_CDR_FLAG_POST_DISABLED
 	if (myrpt->pchannel->cdr)
 		ast_set_flag(myrpt->pchannel->cdr,AST_CDR_FLAG_POST_DISABLED);
@@ -13987,8 +14022,8 @@ static int rpt_exec(struct ast_channel *chan, const char *data)
 	myrpt->tele.prev = &myrpt->tele;
 	myrpt->newkey = 0;
 	rpt_mutex_unlock(&myrpt->lock);
-	ast_set_write_format(chan, AST_FORMAT_SLINEAR);
-	ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+	ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR);
+	ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 	rem_rx = 0;
 	remkeyed = 0;
 	/* if we are on 2w loop and are a remote, turn EC on */
diff --git a/apps/app_sms.c b/apps/app_sms.c
index b5c471b8eea6a6487da3ece12eb8f8c7af457482..07af71d1cd0b69ce707391a68582d27496893bc4 100644
--- a/apps/app_sms.c
+++ b/apps/app_sms.c
@@ -1603,7 +1603,7 @@ static int sms_generate(struct ast_channel *chan, void *data, int len, int sampl
 	buf = alloca(len);
 
 	f.frametype = AST_FRAME_VOICE;
-	f.subclass.codec = __OUT_FMT;
+	ast_format_set(&f.subclass.format, __OUT_FMT, 0);
 	f.datalen = samples * sizeof(*buf);
 	f.offset = AST_FRIENDLY_OFFSET;
 	f.mallocd = 0;
@@ -2001,9 +2001,9 @@ static int sms_exec(struct ast_channel *chan, const char *data)
 		sms_messagetx(&h);
 	}
 
-	res = ast_set_write_format(chan, __OUT_FMT);
+	res = ast_set_write_format_by_id(chan, __OUT_FMT);
 	if (res >= 0) {
-		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 	}
 	if (res < 0) {
 		ast_log(LOG_ERROR, "Unable to set to linear mode, giving up\n");
diff --git a/apps/app_speech_utils.c b/apps/app_speech_utils.c
index 0323f7c47100d709a1fb0611fed4627c51e5fe75..fe99157e95ae66a5f5989170e843c48e3dc42d5d 100644
--- a/apps/app_speech_utils.c
+++ b/apps/app_speech_utils.c
@@ -642,7 +642,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
 	int res = 0, done = 0, started = 0, quieted = 0, max_dtmf_len = 0;
 	struct ast_speech *speech = find_speech(chan);
 	struct ast_frame *f = NULL;
-	int oldreadformat = AST_FORMAT_SLINEAR;
+	struct ast_format oldreadformat;
 	char dtmf[AST_MAX_EXTENSION] = "";
 	struct timeval start = { 0, 0 }, current;
 	struct ast_datastore *datastore = NULL;
@@ -658,6 +658,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
 	parse = ast_strdupa(data);
 	AST_STANDARD_APP_ARGS(args, parse);
 
+	ast_format_clear(&oldreadformat);
 	if (speech == NULL)
 		return -1;
 
@@ -673,10 +674,10 @@ static int speech_background(struct ast_channel *chan, const char *data)
 	}
 
 	/* Record old read format */
-	oldreadformat = chan->readformat;
+	ast_format_copy(&oldreadformat, &chan->readformat);
 
 	/* Change read format to be signed linear */
-	if (ast_set_read_format(chan, speech->format))
+	if (ast_set_read_format(chan, &speech->format))
 		return -1;
 
 	if (!ast_strlen_zero(args.soundfile)) {
@@ -881,7 +882,7 @@ static int speech_background(struct ast_channel *chan, const char *data)
 			ast_channel_datastore_remove(chan, datastore);
 	} else {
 		/* Channel is okay so restore read format */
-		ast_set_read_format(chan, oldreadformat);
+		ast_set_read_format(chan, &oldreadformat);
 	}
 
 	return 0;
diff --git a/apps/app_talkdetect.c b/apps/app_talkdetect.c
index 615929e9430079674421143a75fa1cf5037f12c2..545261c72f2b30d59889fdeb6aff263291d2563f 100644
--- a/apps/app_talkdetect.c
+++ b/apps/app_talkdetect.c
@@ -87,7 +87,7 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
 	int analysistime = -1;
 	int continue_analysis = 1;
 	int x;
-	int origrformat = 0;
+	struct ast_format origrformat;
 	struct ast_dsp *dsp = NULL;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(filename);
@@ -96,7 +96,8 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
 		AST_APP_ARG(max);
 		AST_APP_ARG(analysistime);
 	);
-	
+
+	ast_format_clear(&origrformat);
 	if (ast_strlen_zero(data)) {
 		ast_log(LOG_WARNING, "BackgroundDetect requires an argument (filename)\n");
 		return -1;
@@ -126,8 +127,8 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
 			}
 		}
 
-		origrformat = chan->readformat;
-		if ((ast_set_read_format(chan, AST_FORMAT_SLINEAR))) {
+		ast_format_copy(&origrformat, &chan->readformat);
+		if ((ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR))) {
 			ast_log(LOG_WARNING, "Unable to set read format to linear!\n");
 			res = -1;
 			break;
@@ -182,7 +183,7 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
 						ast_frfree(fr);
 						break;
 					}
-				} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass.codec == AST_FORMAT_SLINEAR) && continue_analysis) {
+				} else if ((fr->frametype == AST_FRAME_VOICE) && (fr->subclass.format.id == AST_FORMAT_SLINEAR) && continue_analysis) {
 					int totalsilence;
 					int ms;
 					res = ast_dsp_silence(dsp, fr, &totalsilence);
@@ -228,9 +229,9 @@ static int background_detect_exec(struct ast_channel *chan, const char *data)
 	} while (0);
 
 	if (res > -1) {
-		if (origrformat && ast_set_read_format(chan, origrformat)) {
+		if (origrformat.id && ast_set_read_format(chan, &origrformat)) {
 			ast_log(LOG_WARNING, "Failed to restore read format for %s to %s\n", 
-				chan->name, ast_getformatname(origrformat));
+				chan->name, ast_getformatname(&origrformat));
 		}
 	}
 	if (dsp) {
diff --git a/apps/app_test.c b/apps/app_test.c
index a7aa7b65707e4060f1d39db4501399b9cab2dec3..7d0214a59a28d26d611566e3de4b2795a2a72046 100644
--- a/apps/app_test.c
+++ b/apps/app_test.c
@@ -87,9 +87,10 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
 	short *foo;
 	struct timeval start;
 	struct ast_frame *f;
-	int rformat;
-	rformat = chan->readformat;
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
+	struct ast_format rformat;
+
+	ast_format_copy(&rformat, &chan->readformat);
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_log(LOG_NOTICE, "Unable to set to linear mode!\n");
 		return -1;
 	}
@@ -106,7 +107,7 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
 			res = -1;
 			break;
 		}
-		if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.codec == AST_FORMAT_SLINEAR)) {
+		if ((f->frametype == AST_FRAME_VOICE) && (f->subclass.format.id == AST_FORMAT_SLINEAR)) {
 			foo = (short *)f->data.ptr;
 			for (x=0;x<f->samples;x++) {
 				noise += abs(foo[x]);
@@ -116,8 +117,8 @@ static int measurenoise(struct ast_channel *chan, int ms, char *who)
 		ast_frfree(f);
 	}
 
-	if (rformat) {
-		if (ast_set_read_format(chan, rformat)) {
+	if (rformat.id) {
+		if (ast_set_read_format(chan, &rformat)) {
 			ast_log(LOG_NOTICE, "Unable to restore original format!\n");
 			return -1;
 		}
diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c
index 166df4c94ae497ebce406c34168bfeec9c62a390..f7882c20da88c5ea0796bec9b97b50035cc9f729 100644
--- a/apps/app_voicemail.c
+++ b/apps/app_voicemail.c
@@ -12347,11 +12347,11 @@ AST_TEST_DEFINE(test_voicemail_vmsayname)
 	}
 
 	/* normally this is done in the channel driver */
-	test_channel1->nativeformats = AST_FORMAT_GSM;
-	test_channel1->writeformat = AST_FORMAT_GSM;
-	test_channel1->rawwriteformat = AST_FORMAT_GSM;
-	test_channel1->readformat = AST_FORMAT_GSM;
-	test_channel1->rawreadformat = AST_FORMAT_GSM;
+	ast_format_set(&test_channel1->writeformat, AST_FORMAT_GSM, 0);
+	ast_format_cap_add(test_channel1->nativeformats, &test_channel1->writeformat);
+	ast_format_set(&test_channel1->rawwriteformat, AST_FORMAT_GSM, 0);
+	ast_format_set(&test_channel1->readformat, AST_FORMAT_GSM, 0);
+	ast_format_set(&test_channel1->rawreadformat, AST_FORMAT_GSM, 0);
 	test_channel1->tech = &fake_tech;
 
 	ast_test_status_update(test, "Test playing of extension when greeting is not available...\n");
diff --git a/apps/app_waitforsilence.c b/apps/app_waitforsilence.c
index fb76f913486c4d3b408442abb814e64e732d9ed8..fe4b1e14dca41b57e6118c19273b294e77e642fd 100644
--- a/apps/app_waitforsilence.c
+++ b/apps/app_waitforsilence.c
@@ -125,7 +125,7 @@ static char *app_noise = "WaitForNoise";
 static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart, int timeout, int wait_for_silence) {
 	struct ast_frame *f = NULL;
 	int dsptime = 0;
-	int rfmt = 0;
+	struct ast_format rfmt;
 	int res = 0;
 	struct ast_dsp *sildet;	 /* silence detector dsp */
  	time_t now;
@@ -134,8 +134,8 @@ static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart,
 	int (*ast_dsp_func)(struct ast_dsp*, struct ast_frame*, int*) =
 				wait_for_silence ? ast_dsp_silence : ast_dsp_noise;
 
-	rfmt = chan->readformat; /* Set to linear mode */
-	if ((res = ast_set_read_format(chan, AST_FORMAT_SLINEAR)) < 0) {
+	ast_format_copy(&rfmt, &chan->readformat); /* Set to linear mode */
+	if ((res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) < 0) {
 		ast_log(LOG_WARNING, "Unable to set channel to linear mode, giving up\n");
 		return -1;
 	}
@@ -195,8 +195,8 @@ static int do_waiting(struct ast_channel *chan, int timereqd, time_t waitstart,
 	}
 
 
-	if (rfmt && ast_set_read_format(chan, rfmt)) {
-		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
+	if (rfmt.id && ast_set_read_format(chan, &rfmt)) {
+		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), chan->name);
 	}
 	ast_dsp_free(sildet);
 	return res;
diff --git a/bridges/bridge_multiplexed.c b/bridges/bridge_multiplexed.c
index 5206731341346ef7336b21110269f1c72fd3e539..0d2b3e254c335f54be59a94b9943ea47de625274 100644
--- a/bridges/bridge_multiplexed.c
+++ b/bridges/bridge_multiplexed.c
@@ -306,7 +306,9 @@ static int multiplexed_bridge_join(struct ast_bridge *bridge, struct ast_bridge_
 		return 0;
 	}
 
-	if (((c0->writeformat == c1->readformat) && (c0->readformat == c1->writeformat) && (c0->nativeformats == c1->nativeformats))) {
+	if ((ast_format_cmp(&c0->writeformat, &c1->readformat) == AST_FORMAT_CMP_EQUAL) &&
+		(ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_EQUAL) &&
+		(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
 		return 0;
 	}
 
@@ -373,7 +375,6 @@ static struct ast_bridge_technology multiplexed_bridge = {
 	.name = "multiplexed_bridge",
 	.capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX,
 	.preference = AST_BRIDGE_PREFERENCE_HIGH,
-	.formats = AST_FORMAT_AUDIO_MASK | AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK,
 	.create = multiplexed_bridge_create,
 	.destroy = multiplexed_bridge_destroy,
 	.join = multiplexed_bridge_join,
@@ -388,6 +389,7 @@ static int unload_module(void)
 	int res = ast_bridge_technology_unregister(&multiplexed_bridge);
 
 	ao2_ref(multiplexed_threads, -1);
+	multiplexed_bridge.format_capabilities = ast_format_cap_destroy(multiplexed_bridge.format_capabilities);
 
 	return res;
 }
@@ -397,7 +399,12 @@ static int load_module(void)
 	if (!(multiplexed_threads = ao2_container_alloc(MULTIPLEXED_BUCKETS, NULL, NULL))) {
 		return AST_MODULE_LOAD_DECLINE;
 	}
-
+	if (!(multiplexed_bridge.format_capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_AUDIO);
+	ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_VIDEO);
+	ast_format_cap_add_all_by_type(multiplexed_bridge.format_capabilities, AST_FORMAT_TYPE_TEXT);
 	return ast_bridge_technology_register(&multiplexed_bridge);
 }
 
diff --git a/bridges/bridge_simple.c b/bridges/bridge_simple.c
index 0dbcd25d2fdb73afb85862b3d796cbe9acdf5f74..72b91087adfda9885e644249cc7907d1834b5b14 100644
--- a/bridges/bridge_simple.c
+++ b/bridges/bridge_simple.c
@@ -51,7 +51,9 @@ static int simple_bridge_join(struct ast_bridge *bridge, struct ast_bridge_chann
 	}
 
 	/* See if we need to make these compatible */
-	if (((c0->writeformat == c1->readformat) && (c0->readformat == c1->writeformat) && (c0->nativeformats == c1->nativeformats))) {
+	if ((ast_format_cmp(&c0->writeformat, &c1->readformat) == AST_FORMAT_CMP_EQUAL) &&
+		(ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_EQUAL) &&
+		(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
 		return 0;
 	}
 
@@ -85,18 +87,25 @@ static struct ast_bridge_technology simple_bridge = {
 	.name = "simple_bridge",
 	.capabilities = AST_BRIDGE_CAPABILITY_1TO1MIX | AST_BRIDGE_CAPABILITY_THREAD,
 	.preference = AST_BRIDGE_PREFERENCE_MEDIUM,
-	.formats = AST_FORMAT_AUDIO_MASK | AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK,
 	.join = simple_bridge_join,
 	.write = simple_bridge_write,
 };
 
 static int unload_module(void)
 {
+	ast_format_cap_destroy(simple_bridge.format_capabilities);
 	return ast_bridge_technology_unregister(&simple_bridge);
 }
 
 static int load_module(void)
 {
+	if (!(simple_bridge.format_capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_AUDIO);
+	ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_VIDEO);
+	ast_format_cap_add_all_by_type(simple_bridge.format_capabilities, AST_FORMAT_TYPE_TEXT);
+
 	return ast_bridge_technology_register(&simple_bridge);
 }
 
diff --git a/bridges/bridge_softmix.c b/bridges/bridge_softmix.c
index 69d13a2b6aabe872f550e5d919b78b9515a9478f..b25ab99fa82606d1063ba6d82e7f7df0cddf3e6b 100644
--- a/bridges/bridge_softmix.c
+++ b/bridges/bridge_softmix.c
@@ -126,9 +126,9 @@ static int softmix_bridge_join(struct ast_bridge *bridge, struct ast_bridge_chan
 	/* Setup frame parameters */
 	sc->frame.frametype = AST_FRAME_VOICE;
 #ifdef SOFTMIX_16_SUPPORT
-	sc->frame.subclass.codec = AST_FORMAT_SLINEAR16;
+	ast_format_set(&sc->frame.subclass.format, AST_FORMAT_SLINEAR16, 0);
 #else
-	sc->frame.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&sc->frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 #endif
 	sc->frame.data.ptr = sc->final_buf;
 	sc->frame.datalen = SOFTMIX_DATALEN;
@@ -171,9 +171,9 @@ static enum ast_bridge_write_result softmix_bridge_write(struct ast_bridge *brid
 
 	/* If a frame was provided add it to the smoother */
 #ifdef SOFTMIX_16_SUPPORT
-	if (frame->frametype == AST_FRAME_VOICE && frame->subclass.codec == AST_FORMAT_SLINEAR16) {
+	if (frame->frametype == AST_FRAME_VOICE && frame->subclass.format.id == AST_FORMAT_SLINEAR16) {
 #else
-	if (frame->frametype == AST_FRAME_VOICE && frame->subclass.codec == AST_FORMAT_SLINEAR) {
+	if (frame->frametype == AST_FRAME_VOICE && frame->subclass.format.id == AST_FORMAT_SLINEAR) {
 #endif
 		ast_slinfactory_feed(&sc->factory, frame);
 	}
@@ -282,11 +282,6 @@ static struct ast_bridge_technology softmix_bridge = {
 	.name = "softmix",
 	.capabilities = AST_BRIDGE_CAPABILITY_MULTIMIX | AST_BRIDGE_CAPABILITY_THREAD | AST_BRIDGE_CAPABILITY_MULTITHREADED,
 	.preference = AST_BRIDGE_PREFERENCE_LOW,
-#ifdef SOFTMIX_16_SUPPORT
-	.formats = AST_FORMAT_SLINEAR16,
-#else
-	.formats = AST_FORMAT_SLINEAR,
-#endif
 	.create = softmix_bridge_create,
 	.destroy = softmix_bridge_destroy,
 	.join = softmix_bridge_join,
@@ -298,11 +293,21 @@ static struct ast_bridge_technology softmix_bridge = {
 
 static int unload_module(void)
 {
+	ast_format_cap_destroy(softmix_bridge.format_capabilities);
 	return ast_bridge_technology_unregister(&softmix_bridge);
 }
 
 static int load_module(void)
 {
+	struct ast_format tmp;
+	if (!(softmix_bridge.format_capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+#ifdef SOFTMIX_16_SUPPORT
+	ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR16, 0));
+#else
+	ast_format_cap_add(softmix_bridge.format_capabilities, ast_format_set(&tmp, AST_FORMAT_SLINEAR, 0));
+#endif
 	return ast_bridge_technology_register(&softmix_bridge);
 }
 
diff --git a/channels/chan_agent.c b/channels/chan_agent.c
index 7cf5e69d76c541e5cf2c9cf02ba9853a7f26667a..9e1dfed9edbc827b953893c32fd2707cc55ad851 100644
--- a/channels/chan_agent.c
+++ b/channels/chan_agent.c
@@ -297,19 +297,19 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt);	/*!< Holds the list of agents (l
 
 #define CHECK_FORMATS(ast, p) do { \
 	if (p->chan) {\
-		if (ast->nativeformats != p->chan->nativeformats) { \
+		if (!(ast_format_cap_identical(ast->nativeformats, p->chan->nativeformats))) { \
 			char tmp1[256], tmp2[256]; \
 			ast_debug(1, "Native formats changing from '%s' to '%s'\n", ast_getformatname_multiple(tmp1, sizeof(tmp1), ast->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), p->chan->nativeformats)); \
 			/* Native formats changed, reset things */ \
-			ast->nativeformats = p->chan->nativeformats; \
-			ast_debug(1, "Resetting read to '%s' and write to '%s'\n", ast_getformatname_multiple(tmp1, sizeof(tmp1), ast->readformat), ast_getformatname_multiple(tmp2, sizeof(tmp2), ast->writeformat));\
-			ast_set_read_format(ast, ast->readformat); \
-			ast_set_write_format(ast, ast->writeformat); \
+			ast_format_cap_copy(ast->nativeformats, p->chan->nativeformats); \
+			ast_debug(1, "Resetting read to '%s' and write to '%s'\n", ast_getformatname(&ast->readformat), ast_getformatname(&ast->writeformat));\
+			ast_set_read_format(ast, &ast->readformat); \
+			ast_set_write_format(ast, &ast->writeformat); \
 		} \
-		if (p->chan->readformat != ast->rawreadformat && !p->chan->generator)  \
-			ast_set_read_format(p->chan, ast->rawreadformat); \
-		if (p->chan->writeformat != ast->rawwriteformat && !p->chan->generator) \
-			ast_set_write_format(p->chan, ast->rawwriteformat); \
+		if ((ast_format_cmp(&p->chan->readformat, &ast->rawreadformat) != AST_FORMAT_CMP_EQUAL) && !p->chan->generator)  \
+			ast_set_read_format(p->chan, &ast->rawreadformat); \
+		if ((ast_format_cmp(&p->chan->writeformat, &ast->rawwriteformat) != AST_FORMAT_CMP_EQUAL) && !p->chan->generator) \
+			ast_set_write_format(p->chan, &ast->rawwriteformat); \
 	} \
 } while(0)
 
@@ -329,7 +329,7 @@ static AST_LIST_HEAD_STATIC(agents, agent_pvt);	/*!< Holds the list of agents (l
 } while(0)
 
 /*--- Forward declarations */
-static struct ast_channel *agent_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *agent_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int agent_devicestate(void *data);
 static int agent_digit_begin(struct ast_channel *ast, char digit);
 static int agent_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -349,10 +349,9 @@ static int agent_set_base_channel(struct ast_channel *chan, struct ast_channel *
 static int agent_logoff(const char *agent, int soft);
 
 /*! \brief Channel interface description for PBX integration */
-static const struct ast_channel_tech agent_tech = {
+static struct ast_channel_tech agent_tech = {
 	.type = "Agent",
 	.description = tdesc,
-	.capabilities = -1,
 	.requester = agent_request,
 	.devicestate = agent_devicestate,
 	.send_digit_begin = agent_digit_begin,
@@ -695,7 +694,7 @@ static int agent_write(struct ast_channel *ast, struct ast_frame *f)
 	else {
 		if ((f->frametype != AST_FRAME_VOICE) ||
 		    (f->frametype != AST_FRAME_VIDEO) ||
-		    (f->subclass.codec == p->chan->writeformat)) {
+		    (ast_format_cmp(&f->subclass.format, &p->chan->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) {
 			res = ast_write(p->chan, f);
 		} else {
 			ast_debug(1, "Dropping one incompatible %s frame on '%s' to '%s'\n", 
@@ -799,10 +798,11 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
 		ast_debug(3, "Waited for stream, result '%d'\n", res);
 	}
 	if (!res) {
-		res = ast_set_read_format(p->chan, ast_best_codec(p->chan->nativeformats));
+		struct ast_format tmpfmt;
+		res = ast_set_read_format_from_cap(p->chan, p->chan->nativeformats);
 		ast_debug(3, "Set read format, result '%d'\n", res);
 		if (res)
-			ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
+			ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(&tmpfmt));
 	} else {
 		/* Agent hung-up */
 		p->chan = NULL;
@@ -810,10 +810,11 @@ static int agent_call(struct ast_channel *ast, char *dest, int timeout)
 	}
 
 	if (!res) {
-		res = ast_set_write_format(p->chan, ast_best_codec(p->chan->nativeformats));
+		struct ast_format tmpfmt;
+		res = ast_set_write_format_from_cap(p->chan, p->chan->nativeformats);
 		ast_debug(3, "Set write format, result '%d'\n", res);
 		if (res)
-			ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(p->chan->nativeformats)));
+			ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(&tmpfmt));
 	}
 	if(!res) {
 		/* Call is immediately up, or might need ack */
@@ -1047,21 +1048,21 @@ static struct ast_channel *agent_new(struct agent_pvt *p, int state, const char
 
 	tmp->tech = &agent_tech;
 	if (p->chan) {
-		tmp->nativeformats = p->chan->nativeformats;
-		tmp->writeformat = p->chan->writeformat;
-		tmp->rawwriteformat = p->chan->writeformat;
-		tmp->readformat = p->chan->readformat;
-		tmp->rawreadformat = p->chan->readformat;
+		ast_format_cap_copy(tmp->nativeformats, p->chan->nativeformats);
+		ast_format_copy(&tmp->writeformat, &p->chan->writeformat);
+		ast_format_copy(&tmp->rawwriteformat, &p->chan->writeformat);
+		ast_format_copy(&tmp->readformat, &p->chan->readformat);
+		ast_format_copy(&tmp->rawreadformat, &p->chan->readformat);
 		ast_string_field_set(tmp, language, p->chan->language);
 		ast_copy_string(tmp->context, p->chan->context, sizeof(tmp->context));
 		ast_copy_string(tmp->exten, p->chan->exten, sizeof(tmp->exten));
 		/* XXX Is this really all we copy form the originating channel?? */
 	} else {
-		tmp->nativeformats = AST_FORMAT_SLINEAR;
-		tmp->writeformat = AST_FORMAT_SLINEAR;
-		tmp->rawwriteformat = AST_FORMAT_SLINEAR;
-		tmp->readformat = AST_FORMAT_SLINEAR;
-		tmp->rawreadformat = AST_FORMAT_SLINEAR;
+		ast_format_set(&tmp->writeformat, AST_FORMAT_SLINEAR, 0);
+		ast_format_set(&tmp->rawwriteformat, AST_FORMAT_SLINEAR, 0);
+		ast_format_set(&tmp->readformat, AST_FORMAT_SLINEAR, 0);
+		ast_format_set(&tmp->rawreadformat, AST_FORMAT_SLINEAR, 0);
+		ast_format_cap_add(tmp->nativeformats, &tmp->writeformat);
 	}
 	/* Safe, agentlock already held */
 	tmp->tech_pvt = p;
@@ -1374,7 +1375,7 @@ static int check_beep(struct agent_pvt *newlyavailable, int needlock)
 }
 
 /*! \brief Part of the Asterisk PBX interface */
-static struct ast_channel *agent_request(const char *type, format_t format, const struct ast_channel* requestor, void *data, int *cause)
+static struct ast_channel *agent_request(const char *type, struct ast_format_cap *cap, const struct ast_channel* requestor, void *data, int *cause)
 {
 	struct agent_pvt *p;
 	struct ast_channel *chan = NULL;
@@ -1997,14 +1998,18 @@ static int login_exec(struct ast_channel *chan, const char *data)
 					AST_LIST_LOCK(&agents);
 					ast_mutex_lock(&p->lock);
 					if (!res) {
-						res = ast_set_read_format(chan, ast_best_codec(chan->nativeformats));
-						if (res)
-							ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(ast_best_codec(chan->nativeformats)));
+						struct ast_format tmpfmt;
+						res = ast_set_read_format_from_cap(chan, chan->nativeformats);
+						if (res) {
+							ast_log(LOG_WARNING, "Unable to set read format to %s\n", ast_getformatname(&tmpfmt));
+						}
 					}
 					if (!res) {
-						res = ast_set_write_format(chan, ast_best_codec(chan->nativeformats));
-						if (res)
-							ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(ast_best_codec(chan->nativeformats)));
+						struct ast_format tmpfmt;
+						res = ast_set_write_format_from_cap(chan, chan->nativeformats);
+						if (res) {
+							ast_log(LOG_WARNING, "Unable to set write format to %s\n", ast_getformatname(&tmpfmt));
+						}
 					}
 					/* Check once more just in case */
 					if (p->chan)
@@ -2024,7 +2029,7 @@ static int login_exec(struct ast_channel *chan, const char *data)
 							snprintf(chan->cdr->channel, sizeof(chan->cdr->channel), "Agent/%s", p->agent);
 						ast_queue_log("NONE", chan->uniqueid, agent, "AGENTLOGIN", "%s", chan->name);
 						ast_verb(2, "Agent '%s' logged in (format %s/%s)\n", p->agent,
-								    ast_getformatname(chan->readformat), ast_getformatname(chan->writeformat));
+								    ast_getformatname(&chan->readformat), ast_getformatname(&chan->writeformat));
 						/* Login this channel and wait for it to go away */
 						p->chan = chan;
 						if (p->ackcall) {
@@ -2418,6 +2423,11 @@ static const struct ast_data_entry agents_data_providers[] = {
  */
 static int load_module(void)
 {
+	if (!(agent_tech.capabilities = ast_format_cap_alloc())) {
+		ast_log(LOG_ERROR, "ast_format_cap_alloc_nolock fail.\n");
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add_all(agent_tech.capabilities);
 	/* Make sure we can register our agent channel type */
 	if (ast_channel_register(&agent_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Agent'\n");
@@ -2477,6 +2487,8 @@ static int unload_module(void)
 		ast_free(p);
 	}
 	AST_LIST_UNLOCK(&agents);
+
+	agent_tech.capabilities = ast_format_cap_destroy(agent_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_alsa.c b/channels/chan_alsa.c
index 120987ae4e549f6ff9e1ad4851f659547435f92a..58382881e7237e74ac74edc24265063a5542edaa 100644
--- a/channels/chan_alsa.c
+++ b/channels/chan_alsa.c
@@ -133,7 +133,7 @@ static int autoanswer = 1;
 static int mute = 0;
 static int noaudiocapture = 0;
 
-static struct ast_channel *alsa_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int alsa_digit(struct ast_channel *c, char digit, unsigned int duration);
 static int alsa_text(struct ast_channel *c, const char *text);
 static int alsa_hangup(struct ast_channel *c);
@@ -144,10 +144,9 @@ static int alsa_write(struct ast_channel *chan, struct ast_frame *f);
 static int alsa_indicate(struct ast_channel *chan, int cond, const void *data, size_t datalen);
 static int alsa_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 
-static const struct ast_channel_tech alsa_tech = {
+static struct ast_channel_tech alsa_tech = {
 	.type = "Console",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR,
 	.requester = alsa_request,
 	.send_digit_end = alsa_digit,
 	.send_text = alsa_text,
@@ -502,7 +501,7 @@ static struct ast_frame *alsa_read(struct ast_channel *chan)
 		}
 
 		f.frametype = AST_FRAME_VOICE;
-		f.subclass.codec = AST_FORMAT_SLINEAR;
+		ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
 		f.samples = FRAME_SIZE;
 		f.datalen = FRAME_SIZE * 2;
 		f.data.ptr = buf;
@@ -572,9 +571,10 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
 
 	tmp->tech = &alsa_tech;
 	ast_channel_set_fd(tmp, 0, readdev);
-	tmp->nativeformats = AST_FORMAT_SLINEAR;
-	tmp->readformat = AST_FORMAT_SLINEAR;
-	tmp->writeformat = AST_FORMAT_SLINEAR;
+	ast_format_set(&tmp->readformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&tmp->writeformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_cap_add(tmp->nativeformats, &tmp->writeformat);
+
 	tmp->tech_pvt = p;
 	if (!ast_strlen_zero(p->context))
 		ast_copy_string(tmp->context, p->context, sizeof(tmp->context));
@@ -596,14 +596,16 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state, const ch
 	return tmp;
 }
 
-static struct ast_channel *alsa_request(const char *type, format_t fmt, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *alsa_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat = fmt;
+	struct ast_format tmpfmt;
 	char buf[256];
 	struct ast_channel *tmp = NULL;
 
-	if (!(fmt &= AST_FORMAT_SLINEAR)) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
+	ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
+
+	if (!(ast_format_cap_iscompatible(cap, &tmpfmt))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
 		return NULL;
 	}
 
@@ -929,6 +931,12 @@ static int load_module(void)
 	struct ast_config *cfg;
 	struct ast_variable *v;
 	struct ast_flags config_flags = { 0 };
+	struct ast_format tmpfmt;
+
+	if (!(alsa_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(alsa_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 
 	/* Copy the default jb config over global_jbconf */
 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -1006,6 +1014,7 @@ static int unload_module(void)
 	if (alsa.owner)
 		return -1;
 
+	alsa_tech.capabilities = ast_format_cap_destroy(alsa_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_bridge.c b/channels/chan_bridge.c
index 8218bdceb9a2f22a68aee540e4ec3b9171366ee2..a58cfcc59b34a51421ffedd5b36c58b45f5dfce1 100644
--- a/channels/chan_bridge.c
+++ b/channels/chan_bridge.c
@@ -46,17 +46,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/app.h"
 #include "asterisk/bridging.h"
 
-static struct ast_channel *bridge_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int bridge_call(struct ast_channel *ast, char *dest, int timeout);
 static int bridge_hangup(struct ast_channel *ast);
 static struct ast_frame *bridge_read(struct ast_channel *ast);
 static int bridge_write(struct ast_channel *ast, struct ast_frame *f);
 static struct ast_channel *bridge_bridgedchannel(struct ast_channel *chan, struct ast_channel *bridge);
 
-static const struct ast_channel_tech bridge_tech = {
+static struct ast_channel_tech bridge_tech = {
 	.type = "Bridge",
 	.description = "Bridge Interaction Channel",
-	.capabilities = -1,
 	.requester = bridge_request,
 	.call = bridge_call,
 	.hangup = bridge_hangup,
@@ -189,9 +188,10 @@ static int bridge_hangup(struct ast_channel *ast)
 }
 
 /*! \brief Called when we want to place a call somewhere, but not actually call it... yet */
-static struct ast_channel *bridge_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *bridge_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct bridge_pvt *p = NULL;
+	struct ast_format slin;
 
 	/* Try to allocate memory for our very minimal pvt structure */
 	if (!(p = ast_calloc(1, sizeof(*p)))) {
@@ -215,11 +215,19 @@ static struct ast_channel *bridge_request(const char *type, format_t format, con
 	/* Setup parameters on both new channels */
 	p->input->tech = p->output->tech = &bridge_tech;
 	p->input->tech_pvt = p->output->tech_pvt = p;
-	p->input->nativeformats = p->output->nativeformats = AST_FORMAT_SLINEAR;
-	p->input->readformat = p->output->readformat = AST_FORMAT_SLINEAR;
-	p->input->rawreadformat = p->output->rawreadformat = AST_FORMAT_SLINEAR;
-	p->input->writeformat = p->output->writeformat = AST_FORMAT_SLINEAR;
-	p->input->rawwriteformat = p->output->rawwriteformat = AST_FORMAT_SLINEAR;
+
+	ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_cap_add(p->input->nativeformats, &slin);
+	ast_format_cap_add(p->output->nativeformats, &slin);
+	ast_format_copy(&p->input->readformat, &slin);
+	ast_format_copy(&p->output->readformat, &slin);
+	ast_format_copy(&p->input->rawreadformat, &slin);
+	ast_format_copy(&p->output->rawreadformat, &slin);
+	ast_format_copy(&p->input->writeformat, &slin);
+	ast_format_copy(&p->output->writeformat, &slin);
+	ast_format_copy(&p->input->rawwriteformat, &slin);
+	ast_format_copy(&p->output->rawwriteformat, &slin);
 
 	return p->input;
 }
@@ -227,6 +235,11 @@ static struct ast_channel *bridge_request(const char *type, format_t format, con
 /*! \brief Load module into PBX, register channel */
 static int load_module(void)
 {
+	if (!(bridge_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+
+	ast_format_cap_add_all(bridge_tech.capabilities);
 	/* Make sure we can register our channel type */
 	if (ast_channel_register(&bridge_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Bridge'\n");
@@ -239,6 +252,7 @@ static int load_module(void)
 static int unload_module(void)
 {
 	ast_channel_unregister(&bridge_tech);
+	bridge_tech.capabilities = ast_format_cap_destroy(bridge_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_console.c b/channels/chan_console.c
index 64c1b87fcdf3ada4b9b9211db6521f663fbc87d3..eb961b6825d141ad06c55a02a703555143ad5689 100644
--- a/channels/chan_console.c
+++ b/channels/chan_console.c
@@ -183,7 +183,7 @@ static struct ast_jb_conf default_jbconf = {
 static struct ast_jb_conf global_jbconf;
 
 /*! Channel Technology Callbacks @{ */
-static struct ast_channel *console_request(const char *type, format_t format,
+static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap,
 	const struct ast_channel *requestor, void *data, int *cause);
 static int console_digit_begin(struct ast_channel *c, char digit);
 static int console_digit_end(struct ast_channel *c, char digit, unsigned int duration);
@@ -198,15 +198,9 @@ static int console_indicate(struct ast_channel *chan, int cond,
 static int console_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 /*! @} */
 
-/*!
- * \brief Formats natively supported by this module.
- */
-#define SUPPORTED_FORMATS ( AST_FORMAT_SLINEAR16 )
-
-static const struct ast_channel_tech console_tech = {
+static struct ast_channel_tech console_tech = {
 	.type = "Console",
 	.description = "Console Channel Driver",
-	.capabilities = SUPPORTED_FORMATS,
 	.requester = console_request,
 	.send_digit_begin = console_digit_begin,
 	.send_digit_end = console_digit_end,
@@ -265,12 +259,12 @@ static void *stream_monitor(void *data)
 	PaError res;
 	struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR16,
 		.src = "console_stream_monitor",
 		.data.ptr = buf,
 		.datalen = sizeof(buf),
 		.samples = sizeof(buf) / sizeof(int16_t),
 	};
+	ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0);
 
 	for (;;) {
 		pthread_testcancel();
@@ -424,9 +418,9 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
 	}
 
 	chan->tech = &console_tech;
-	chan->nativeformats = AST_FORMAT_SLINEAR16;
-	chan->readformat = AST_FORMAT_SLINEAR16;
-	chan->writeformat = AST_FORMAT_SLINEAR16;
+	ast_format_set(&chan->readformat, AST_FORMAT_SLINEAR16, 0);
+	ast_format_set(&chan->writeformat, AST_FORMAT_SLINEAR16, 0);
+	ast_format_cap_add(chan->nativeformats, &chan->readformat);
 	chan->tech_pvt = ref_pvt(pvt);
 
 	pvt->owner = chan;
@@ -448,9 +442,8 @@ static struct ast_channel *console_new(struct console_pvt *pvt, const char *ext,
 	return chan;
 }
 
-static struct ast_channel *console_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *console_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat = format;
 	struct ast_channel *chan = NULL;
 	struct console_pvt *pvt;
 	char buf[512];
@@ -460,9 +453,8 @@ static struct ast_channel *console_request(const char *type, format_t format, co
 		return NULL;
 	}
 
-	format &= SUPPORTED_FORMATS;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
+	if (!(ast_format_cap_has_joint(cap, console_tech.capabilities))) {
+		ast_log(LOG_NOTICE, "Channel requested with unsupported format(s): '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
 		goto return_unref;
 	}
 
@@ -1457,6 +1449,7 @@ static void stop_streams(void)
 
 static int unload_module(void)
 {
+	console_tech.capabilities = ast_format_cap_destroy(console_tech.capabilities);
 	ast_channel_unregister(&console_tech);
 	ast_cli_unregister_multiple(cli_console, ARRAY_LEN(cli_console));
 
@@ -1474,8 +1467,14 @@ static int unload_module(void)
 
 static int load_module(void)
 {
+	struct ast_format tmpfmt;
 	PaError res;
 
+	if (!(console_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(console_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR16, 0));
+
 	init_pvt(&globals, NULL);
 
 	if (!(pvts = ao2_container_alloc(NUM_PVT_BUCKETS, pvt_hash_cb, pvt_cmp_cb)))
diff --git a/channels/chan_dahdi.c b/channels/chan_dahdi.c
index 09f4612590b950e80e4ec1850d738ec646472570..b5f398fdf388b6cd1563b6940b57fdc9a4c565d4 100644
--- a/channels/chan_dahdi.c
+++ b/channels/chan_dahdi.c
@@ -1471,7 +1471,7 @@ static struct dahdi_chan_conf dahdi_chan_conf_default(void)
 }
 
 
-static struct ast_channel *dahdi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int dahdi_digit_begin(struct ast_channel *ast, char digit);
 static int dahdi_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int dahdi_sendtext(struct ast_channel *c, const char *text);
@@ -1490,10 +1490,9 @@ static int dahdi_func_write(struct ast_channel *chan, const char *function, char
 static int dahdi_devicestate(void *data);
 static int dahdi_cc_callback(struct ast_channel *inbound, const char *dest, ast_cc_callback_fn callback);
 
-static const struct ast_channel_tech dahdi_tech = {
+static struct ast_channel_tech dahdi_tech = {
 	.type = "DAHDI",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_ALAW,
 	.requester = dahdi_request,
 	.send_digit_begin = dahdi_digit_begin,
 	.send_digit_end = dahdi_digit_end,
@@ -1679,6 +1678,7 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
 	int res;
 	unsigned char buf[256];
 	int flags;
+	struct ast_format tmpfmt;
 
 	poller.fd = p->subs[SUB_REAL].dfd;
 	poller.events = POLLPRI | POLLIN;
@@ -1714,9 +1714,9 @@ static int my_get_callerid(void *pvt, char *namebuf, char *numbuf, enum analog_e
 		}
 
 		if (p->cid_signalling == CID_SIG_V23_JP) {
-			res = callerid_feed_jp(p->cs, buf, res, AST_LAW(p));
+			res = callerid_feed_jp(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		} else {
-			res = callerid_feed(p->cs, buf, res, AST_LAW(p));
+			res = callerid_feed(p->cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		}
 		if (res < 0) {
 			/*
@@ -1885,6 +1885,7 @@ static int restore_conference(struct dahdi_pvt *p);
 static int my_callwait(void *pvt)
 {
 	struct dahdi_pvt *p = pvt;
+	struct ast_format tmpfmt;
 	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
 	if (p->cidspill) {
 		ast_log(LOG_WARNING, "Spill already exists?!?\n");
@@ -1901,11 +1902,11 @@ static int my_callwait(void *pvt)
 	/* Silence */
 	memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
 	if (!p->callwaitrings && p->callwaitingcallerid) {
-		ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
+		ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		p->callwaitcas = 1;
 		p->cidlen = 2400 + 680 + READ_SIZE * 4;
 	} else {
-		ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
+		ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		p->callwaitcas = 0;
 		p->cidlen = 2400 + READ_SIZE * 4;
 	}
@@ -1918,6 +1919,7 @@ static int my_callwait(void *pvt)
 static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *caller)
 {
 	struct dahdi_pvt *p = pvt;
+	struct ast_format tmpfmt;
 
 	ast_debug(2, "Starting cid spill\n");
 
@@ -1931,7 +1933,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
 			p->cidlen = ast_callerid_generate(p->cidspill,
 				caller->id.name.str,
 				caller->id.number.str,
-				AST_LAW(p));
+				ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		} else {
 			ast_verb(3, "CPE supports Call Waiting Caller*ID.  Sending '%s/%s'\n",
 				caller->id.name.str, caller->id.number.str);
@@ -1940,7 +1942,7 @@ static int my_send_callerid(void *pvt, int cwcid, struct ast_party_caller *calle
 			p->cidlen = ast_callerid_callwaiting_generate(p->cidspill,
 				caller->id.name.str,
 				caller->id.number.str,
-				AST_LAW(p));
+				ast_format_set(&tmpfmt, AST_LAW(p), 0));
 			p->cidlen += READ_SIZE * 4;
 		}
 		p->cidpos = 0;
@@ -5106,12 +5108,14 @@ static int restore_conference(struct dahdi_pvt *p)
 
 static int send_cwcidspill(struct dahdi_pvt *p)
 {
+	struct ast_format tmpfmt;
+
 	p->callwaitcas = 0;
 	p->cidcwexpire = 0;
 	p->cid_suppress_expire = 0;
 	if (!(p->cidspill = ast_malloc(MAX_CALLERID_SIZE)))
 		return -1;
-	p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, AST_LAW(p));
+	p->cidlen = ast_callerid_callwaiting_generate(p->cidspill, p->callwait_name, p->callwait_num, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 	/* Make sure we account for the end */
 	p->cidlen += READ_SIZE * 4;
 	p->cidpos = 0;
@@ -5186,6 +5190,7 @@ static int send_callerid(struct dahdi_pvt *p)
 static int dahdi_callwait(struct ast_channel *ast)
 {
 	struct dahdi_pvt *p = ast->tech_pvt;
+	struct ast_format tmpfmt;
 	p->callwaitingrepeat = CALLWAITING_REPEAT_SAMPLES;
 	if (p->cidspill) {
 		ast_log(LOG_WARNING, "Spill already exists?!?\n");
@@ -5202,11 +5207,11 @@ static int dahdi_callwait(struct ast_channel *ast)
 	/* Silence */
 	memset(p->cidspill, 0x7f, 2400 + 600 + READ_SIZE * 4);
 	if (!p->callwaitrings && p->callwaitingcallerid) {
-		ast_gen_cas(p->cidspill, 1, 2400 + 680, AST_LAW(p));
+		ast_gen_cas(p->cidspill, 1, 2400 + 680, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		p->callwaitcas = 1;
 		p->cidlen = 2400 + 680 + READ_SIZE * 4;
 	} else {
-		ast_gen_cas(p->cidspill, 1, 2400, AST_LAW(p));
+		ast_gen_cas(p->cidspill, 1, 2400, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 		p->callwaitcas = 0;
 		p->cidlen = 2400 + READ_SIZE * 4;
 	}
@@ -8823,15 +8828,15 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
 		return &p->subs[idx].f;
 	}
 
-	if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
+	if (ast->rawreadformat.id == AST_FORMAT_SLINEAR) {
 		if (!p->subs[idx].linear) {
 			p->subs[idx].linear = 1;
 			res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
 			if (res)
 				ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to linear mode.\n", p->channel, idx);
 		}
-	} else if ((ast->rawreadformat == AST_FORMAT_ULAW) ||
-		(ast->rawreadformat == AST_FORMAT_ALAW)) {
+	} else if ((ast->rawreadformat.id == AST_FORMAT_ULAW) ||
+		(ast->rawreadformat.id == AST_FORMAT_ALAW)) {
 		if (p->subs[idx].linear) {
 			p->subs[idx].linear = 0;
 			res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
@@ -8839,7 +8844,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
 				ast_log(LOG_WARNING, "Unable to set channel %d (index %d) to companded mode.\n", p->channel, idx);
 		}
 	} else {
-		ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(ast->rawreadformat));
+		ast_log(LOG_WARNING, "Don't know how to read frames in format %s\n", ast_getformatname(&ast->rawreadformat));
 		ast_mutex_unlock(&p->lock);
 		return NULL;
 	}
@@ -8931,7 +8936,7 @@ static struct ast_frame *dahdi_read(struct ast_channel *ast)
 	}
 
 	p->subs[idx].f.frametype = AST_FRAME_VOICE;
-	p->subs[idx].f.subclass.codec = ast->rawreadformat;
+	ast_format_copy(&p->subs[idx].f.subclass.format, &ast->rawreadformat);
 	p->subs[idx].f.samples = READ_SIZE;
 	p->subs[idx].f.mallocd = 0;
 	p->subs[idx].f.offset = AST_FRIENDLY_OFFSET;
@@ -9101,10 +9106,10 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
 			ast_log(LOG_WARNING, "Don't know what to do with frame type '%d'\n", frame->frametype);
 		return 0;
 	}
-	if ((frame->subclass.codec != AST_FORMAT_SLINEAR) &&
-		(frame->subclass.codec != AST_FORMAT_ULAW) &&
-		(frame->subclass.codec != AST_FORMAT_ALAW)) {
-		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
+	if ((frame->subclass.format.id != AST_FORMAT_SLINEAR) &&
+		(frame->subclass.format.id != AST_FORMAT_ULAW) &&
+		(frame->subclass.format.id != AST_FORMAT_ALAW)) {
+		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
 		return -1;
 	}
 	if (p->dialing) {
@@ -9124,7 +9129,7 @@ static int dahdi_write(struct ast_channel *ast, struct ast_frame *frame)
 	if (!frame->data.ptr || !frame->datalen)
 		return 0;
 
-	if (frame->subclass.codec == AST_FORMAT_SLINEAR) {
+	if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
 		if (!p->subs[idx].linear) {
 			p->subs[idx].linear = 1;
 			res = dahdi_setlinear(p->subs[idx].dfd, p->subs[idx].linear);
@@ -9316,7 +9321,7 @@ static struct ast_str *create_channel_name(struct dahdi_pvt *i)
 static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpbx, int idx, int law, const char *linkedid)
 {
 	struct ast_channel *tmp;
-	format_t deflaw;
+	struct ast_format deflaw;
 	int x;
 	int features;
 	struct ast_str *chan_name;
@@ -9327,6 +9332,7 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
 		return NULL;
 	}
 
+	ast_format_clear(&deflaw);
 #if defined(HAVE_PRI)
 	/*
 	 * The dnid has been stuffed with the called-number[:subaddress]
@@ -9354,9 +9360,9 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
 	if (law) {
 		i->law = law;
 		if (law == DAHDI_LAW_ALAW) {
-			deflaw = AST_FORMAT_ALAW;
+			ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
 		} else {
-			deflaw = AST_FORMAT_ULAW;
+			ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
 		}
 	} else {
 		switch (i->sig) {
@@ -9370,18 +9376,18 @@ static struct ast_channel *dahdi_new(struct dahdi_pvt *i, int state, int startpb
 			break;
 		}
 		if (i->law_default == DAHDI_LAW_ALAW) {
-			deflaw = AST_FORMAT_ALAW;
+			ast_format_set(&deflaw, AST_FORMAT_ALAW, 0);
 		} else {
-			deflaw = AST_FORMAT_ULAW;
+			ast_format_set(&deflaw, AST_FORMAT_ULAW, 0);
 		}
 	}
 	ast_channel_set_fd(tmp, 0, i->subs[idx].dfd);
-	tmp->nativeformats = deflaw;
+	ast_format_cap_add(tmp->nativeformats, &deflaw);
 	/* Start out assuming ulaw since it's smaller :) */
-	tmp->rawreadformat = deflaw;
-	tmp->readformat = deflaw;
-	tmp->rawwriteformat = deflaw;
-	tmp->writeformat = deflaw;
+	ast_format_copy(&tmp->rawreadformat, &deflaw);
+	ast_format_copy(&tmp->readformat, &deflaw);
+	ast_format_copy(&tmp->rawwriteformat, &deflaw);
+	ast_format_copy(&tmp->writeformat, &deflaw);
 	i->subs[idx].linear = 0;
 	dahdi_setlinear(i->subs[idx].dfd, i->subs[idx].linear);
 	features = 0;
@@ -9619,6 +9625,7 @@ static void *analog_ss_thread(void *data)
 	int len = 0;
 	int res;
 	int idx;
+	struct ast_format tmpfmt;
 
 	ast_mutex_lock(&ss_thread_lock);
 	ss_thread_count++;
@@ -10279,9 +10286,9 @@ static void *analog_ss_thread(void *data)
 							samples += res;
 
 							if (p->cid_signalling == CID_SIG_V23_JP) {
-								res = callerid_feed_jp(cs, buf, res, AST_LAW(p));
+								res = callerid_feed_jp(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 							} else {
-								res = callerid_feed(cs, buf, res, AST_LAW(p));
+								res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 							}
 							if (res < 0) {
 								/*
@@ -10550,7 +10557,7 @@ static void *analog_ss_thread(void *data)
 								}
 							}
 							samples += res;
-							res = callerid_feed(cs, buf, res, AST_LAW(p));
+							res = callerid_feed(cs, buf, res, ast_format_set(&tmpfmt, AST_LAW(p), 0));
 							if (res < 0) {
 								/*
 								 * The previous diagnostic message output likely
@@ -10718,7 +10725,7 @@ struct mwi_thread_data {
 	size_t len;
 };
 
-static int calc_energy(const unsigned char *buf, int len, format_t law)
+static int calc_energy(const unsigned char *buf, int len, enum ast_format_id law)
 {
 	int x;
 	int sum = 0;
@@ -10743,6 +10750,7 @@ static void *mwi_thread(void *data)
 	int i, res;
 	unsigned int spill_done = 0;
 	int spill_result = -1;
+	struct ast_format tmpfmt;
 
 	if (!(cs = callerid_new(mtd->pvt->cid_signalling))) {
 		mtd->pvt->mwimonitoractive = 0;
@@ -10750,7 +10758,7 @@ static void *mwi_thread(void *data)
 		return NULL;
 	}
 
-	callerid_feed(cs, mtd->buf, mtd->len, AST_LAW(mtd->pvt));
+	callerid_feed(cs, mtd->buf, mtd->len, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0));
 
 	bump_gains(mtd->pvt);
 
@@ -10832,7 +10840,7 @@ static void *mwi_thread(void *data)
 			}
 			samples += res;
 			if (!spill_done) {
-				if ((spill_result = callerid_feed(cs, mtd->buf, res, AST_LAW(mtd->pvt))) < 0) {
+				if ((spill_result = callerid_feed(cs, mtd->buf, res, ast_format_set(&tmpfmt, AST_LAW(mtd->pvt), 0))) < 0) {
 					/*
 					 * The previous diagnostic message output likely
 					 * explains why it failed.
@@ -10891,6 +10899,7 @@ quit_no_clean:
 static int mwi_send_init(struct dahdi_pvt * pvt)
 {
 	int x, res;
+	struct ast_format tmpfmt;
 
 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
 	/* Determine how this spill is to be sent */
@@ -10933,7 +10942,7 @@ static int mwi_send_init(struct dahdi_pvt * pvt)
 	if (pvt->mwisend_fsk) {
 #endif
 		pvt->cidlen = ast_callerid_vmwi_generate(pvt->cidspill, has_voicemail(pvt), CID_MWI_TYPE_MDMF_FULL,
-							 AST_LAW(pvt), pvt->cid_name, pvt->cid_num, 0);
+							 ast_format_set(&tmpfmt, AST_LAW(pvt), 0), pvt->cid_name, pvt->cid_num, 0);
 		pvt->cidpos = 0;
 #ifdef HAVE_DAHDI_LINEREVERSE_VMWI
 	}
@@ -13295,7 +13304,7 @@ static struct dahdi_pvt *determine_starting_point(const char *data, struct dahdi
 	return p;
 }
 
-static struct ast_channel *dahdi_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *dahdi_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	int callwait = 0;
 	struct dahdi_pvt *p;
@@ -16285,6 +16294,8 @@ static int __unload_module(void)
 	}
 #endif	/* defined(HAVE_SS7) */
 	ast_cond_destroy(&ss_thread_complete);
+
+	dahdi_tech.capabilities = ast_format_cap_destroy(dahdi_tech.capabilities);
 	return 0;
 }
 
@@ -18034,10 +18045,18 @@ static const struct ast_data_entry dahdi_data_providers[] = {
 static int load_module(void)
 {
 	int res;
+	struct ast_format tmpfmt;
 #if defined(HAVE_PRI) || defined(HAVE_SS7)
 	int y;
 #endif	/* defined(HAVE_PRI) || defined(HAVE_SS7) */
 
+	if (!(dahdi_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(dahdi_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+
 #ifdef HAVE_PRI
 	memset(pris, 0, sizeof(pris));
 	for (y = 0; y < NUM_SPANS; y++) {
@@ -18146,7 +18165,10 @@ static int dahdi_sendtext(struct ast_channel *c, const char *text)
 		return -1;
 	mybuf = buf;
 	if (p->mate) {
-		int codec = AST_LAW(p);
+		struct ast_format tmp;
+		/* PUT_CLI_MARKMS is a macro and requires a format ptr called codec to be present */
+		struct ast_format *codec = &tmp;
+		ast_format_set(codec, AST_LAW(p), 0);
 		for (x = 0; x < HEADER_MS; x++) {	/* 50 ms of Mark */
 			PUT_CLID_MARKMS;
 		}
diff --git a/channels/chan_gtalk.c b/channels/chan_gtalk.c
index 280cac4b55556ead008954d724b2bafaa589a3df..3bbf161928eb18377eea09dc62962ec7c49f88ba 100644
--- a/channels/chan_gtalk.c
+++ b/channels/chan_gtalk.c
@@ -111,7 +111,6 @@ struct gtalk_pvt {
 	iksrule *ringrule;               /*!< Rule for matching RING request */
 	int initiator;                   /*!< If we're the initiator */
 	int alreadygone;
-	int capability;
 	struct ast_codec_pref prefs;
 	struct gtalk_candidate *theircandidates;
 	struct gtalk_candidate *ourcandidates;
@@ -121,8 +120,9 @@ struct gtalk_pvt {
 	struct ast_channel *owner;       /*!< Master Channel */
 	struct ast_rtp_instance *rtp;             /*!< RTP audio session */
 	struct ast_rtp_instance *vrtp;            /*!< RTP video session */
-	format_t jointcapability;             /*!< Supported capability at both ends (codecs ) */
-	format_t peercapability;
+	struct ast_format_cap *cap;
+	struct ast_format_cap *jointcap;             /*!< Supported capability at both ends (codecs ) */
+	struct ast_format_cap *peercap;
 	struct gtalk_pvt *next;	/* Next entity */
 };
 
@@ -152,7 +152,7 @@ struct gtalk {
 	char context[AST_MAX_CONTEXT];
 	char parkinglot[AST_MAX_CONTEXT];	/*!<  Parkinglot */
 	char accountcode[AST_MAX_ACCOUNT_CODE];	/*!< Account code */
-	format_t capability;
+	struct ast_format_cap *cap;
 	ast_group_t callgroup;	/*!< Call group */
 	ast_group_t pickupgroup;	/*!< Pickup group */
 	int callingpres;		/*!< Calling presentation */
@@ -169,12 +169,12 @@ static const char desc[]		= "Gtalk Channel";
 static const char DEFAULT_CONTEXT[]	= "default";
 static const int DEFAULT_ALLOWGUEST	= 1;
 
-static format_t global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
+static struct ast_format_cap *global_capability;
 
 AST_MUTEX_DEFINE_STATIC(gtalklock); /*!< Protect the interface list (of gtalk_pvt's) */
 
 /* Forward declarations */
-static struct ast_channel *gtalk_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 /*static int gtalk_digit(struct ast_channel *ast, char digit, unsigned int duration);*/
 static int gtalk_sendtext(struct ast_channel *ast, const char *text);
 static int gtalk_digit_begin(struct ast_channel *ast, char digit);
@@ -200,10 +200,9 @@ static int gtalk_parser(void *data, ikspak *pak);
 static int gtalk_create_candidates(struct gtalk *client, struct gtalk_pvt *p, char *sid, char *from, char *to);
 
 /*! \brief PBX interface structure for channel registration */
-static const struct ast_channel_tech gtalk_tech = {
+static struct ast_channel_tech gtalk_tech = {
 	.type = "Gtalk",
 	.description = "Gtalk Channel Driver",
-	.capabilities = AST_FORMAT_AUDIO_MASK,
 	.requester = gtalk_request,
 	.send_text = gtalk_sendtext,
 	.send_digit_begin = gtalk_digit_begin,
@@ -247,6 +246,7 @@ static struct gtalk_container gtalk_list;
 
 static void gtalk_member_destroy(struct gtalk *obj)
 {
+	obj->cap = ast_format_cap_destroy(obj->cap);
 	ast_free(obj);
 }
 
@@ -282,7 +282,7 @@ static struct gtalk *find_gtalk(char *name, char *connection)
 }
 
 
-static int add_codec_to_answer(const struct gtalk_pvt *p, int codec, iks *dcodecs)
+static int add_codec_to_answer(const struct gtalk_pvt *p, struct ast_format *codec, iks *dcodecs)
 {
 	int res = 0;
 	char *format = ast_getformatname(codec);
@@ -392,17 +392,17 @@ static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, in
 	struct gtalk *client = p->parent;
 	iks *iq, *gtalk, *dcodecs, *payload_telephone, *transport;
 	int x;
-	int pref_codec = 0;
-	int alreadysent = 0;
+	struct ast_format_cap *alreadysent;
 	int codecs_num = 0;
 	char *lowerto = NULL;
+	struct ast_format tmpfmt;
 
 	iq = iks_new("iq");
 	gtalk = iks_new("session");
 	dcodecs = iks_new("description");
 	transport = iks_new("transport");
 	payload_telephone = iks_new("payload-type");
-	if (!(iq && gtalk && dcodecs && transport && payload_telephone)){
+	if (!(iq && gtalk && dcodecs && transport && payload_telephone)) {
 		iks_delete(iq);
 		iks_delete(gtalk);
 		iks_delete(dcodecs);
@@ -415,16 +415,23 @@ static int gtalk_invite(struct gtalk_pvt *p, char *to, char *from, char *sid, in
 	iks_insert_attrib(dcodecs, "xmlns", GOOGLE_AUDIO_NS);
 	iks_insert_attrib(dcodecs, "xml:lang", "en");
 
-	for (x = 0; x < 64; x++) {
-		if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
+	if (!(alreadysent = ast_format_cap_alloc_nolock())) {
+		return 0;
+	}
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!(ast_codec_pref_index(&client->prefs, x, &tmpfmt))) {
 			break;
-		if (!(client->capability & pref_codec))
+		}
+		if (!(ast_format_cap_iscompatible(client->cap, &tmpfmt))) {
 			continue;
-		if (alreadysent & pref_codec)
+		}
+		if (ast_format_cap_iscompatible(alreadysent, &tmpfmt)) {
 			continue;
-		codecs_num = add_codec_to_answer(p, pref_codec, dcodecs);
-		alreadysent |= pref_codec;
+		}
+		codecs_num = add_codec_to_answer(p, &tmpfmt, dcodecs);
+		ast_format_cap_add(alreadysent, &tmpfmt);
 	}
+	alreadysent = ast_format_cap_destroy(alreadysent);
 
 	if (codecs_num) {
 		/* only propose DTMF within an audio session */
@@ -544,13 +551,15 @@ static enum ast_rtp_glue_result gtalk_get_rtp_peer(struct ast_channel *chan, str
 	return res;
 }
 
-static format_t gtalk_get_codec(struct ast_channel *chan)
+static void gtalk_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
 	struct gtalk_pvt *p = chan->tech_pvt;
-	return p->peercapability;
+	ast_mutex_lock(&p->lock);
+	ast_format_cap_copy(result, p->peercap);
+	ast_mutex_unlock(&p->lock);
 }
 
-static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+static int gtalk_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
 {
 	struct gtalk_pvt *p;
 
@@ -658,15 +667,15 @@ static int gtalk_is_answered(struct gtalk *client, ikspak *pak)
 	}
 
 	/* Now gather all of the codecs that we are asked for */
-	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(tmp->rtp), &tmp->peercapability, &peernoncodeccapability);
+	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(tmp->rtp), tmp->peercap, &peernoncodeccapability);
 
-	/* at this point, we received an awser from the remote Gtalk client,
+	/* at this point, we received an answer from the remote Gtalk client,
 	   which allows us to compare capabilities */
-	tmp->jointcapability = tmp->capability & tmp->peercapability;
-	if (!tmp->jointcapability) {
-		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->capability),
-			ast_getformatname_multiple(s2, BUFSIZ, tmp->peercapability),
-			ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcapability));
+	ast_format_cap_joint_copy(tmp->cap, tmp->peercap, tmp->jointcap);
+	if (ast_format_cap_is_empty(tmp->jointcap)) {
+		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, tmp->cap),
+			ast_getformatname_multiple(s2, BUFSIZ, tmp->peercap),
+			ast_getformatname_multiple(s3, BUFSIZ, tmp->jointcap));
 		/* close session if capabilities don't match */
 		ast_queue_hangup(tmp->owner);
 
@@ -1018,6 +1027,16 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
 	if (!(tmp = ast_calloc(1, sizeof(*tmp)))) {
 		return NULL;
 	}
+	tmp->cap = ast_format_cap_alloc_nolock();
+	tmp->jointcap = ast_format_cap_alloc_nolock();
+	tmp->peercap = ast_format_cap_alloc_nolock();
+	if (!tmp->jointcap || !tmp->peercap || !tmp->cap) {
+		tmp->cap = ast_format_cap_destroy(tmp->cap);
+		tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
+		tmp->peercap = ast_format_cap_destroy(tmp->peercap);
+		ast_free(tmp);
+		return NULL;
+	}
 
 	memcpy(&tmp->prefs, &client->prefs, sizeof(struct ast_codec_pref));
 
@@ -1046,10 +1065,10 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
 	ast_rtp_codecs_payloads_clear(ast_rtp_instance_get_codecs(tmp->rtp), tmp->rtp);
 
 	/* add user configured codec capabilites */
-	if (client->capability) {
-		tmp->capability = client->capability;
-	} else if (global_capability) {
-		tmp->capability = global_capability;
+	if (!(ast_format_cap_is_empty(client->cap))) {
+		ast_format_cap_copy(tmp->cap, client->cap);
+	} else if (!(ast_format_cap_is_empty(global_capability))) {
+		ast_format_cap_copy(tmp->cap, global_capability);
 	}
 
 	tmp->parent = client;
@@ -1081,9 +1100,9 @@ static struct gtalk_pvt *gtalk_alloc(struct gtalk *client, const char *us, const
 static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i, int state, const char *title, const char *linkedid)
 {
 	struct ast_channel *tmp;
-	int fmt;
-	int what;
 	const char *n2;
+	struct ast_format_cap *what; /* used as SHALLOW COPY DO NOT DESTROY */
+	struct ast_format tmpfmt;
 
 	if (title)
 		n2 = title;
@@ -1098,20 +1117,29 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
 
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
-	if (i->jointcapability)
-		what = i->jointcapability;
-	else if (i->capability)
-		what = i->capability;
-	else
+	if (!(ast_format_cap_is_empty(i->jointcap))) {
+		what = i->jointcap;
+	} else if (i->cap) {
+		what = i->cap;
+	} else {
 		what = global_capability;
+	}
 
 	/* Set Frame packetization */
 	if (i->rtp) {
 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
 	}
 
-	tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
-	fmt = ast_best_codec(tmp->nativeformats);
+	ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
+	ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+
+	ast_format_cap_iter_start(i->jointcap);
+	while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
+		if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
+			ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+		}
+	}
+	ast_format_cap_iter_end(i->jointcap);
 
 	if (i->rtp) {
 		ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
@@ -1124,10 +1152,12 @@ static struct ast_channel *gtalk_new(struct gtalk *client, struct gtalk_pvt *i,
 	if (state == AST_STATE_RING)
 		tmp->rings = 1;
 	tmp->adsicpe = AST_ADSI_UNAVAILABLE;
-	tmp->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	tmp->readformat = fmt;
-	tmp->rawreadformat = fmt;
+
+	ast_best_codec(tmp->nativeformats, &tmpfmt);
+	ast_format_copy(&tmp->writeformat, &tmpfmt);
+	ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+	ast_format_copy(&tmp->readformat, &tmpfmt);
+	ast_format_copy(&tmp->rawreadformat, &tmpfmt);
 	tmp->tech_pvt = i;
 
 	tmp->callgroup = client->callgroup;
@@ -1240,6 +1270,9 @@ static void gtalk_free_pvt(struct gtalk *client, struct gtalk_pvt *p)
 	if (p->vrtp)
 		ast_rtp_instance_destroy(p->vrtp);
 	gtalk_free_candidates(p->theircandidates);
+	p->cap = ast_format_cap_destroy(p->cap);
+	p->jointcap = ast_format_cap_destroy(p->jointcap);
+	p->peercap = ast_format_cap_destroy(p->peercap);
 	ast_free(p);
 }
 
@@ -1341,15 +1374,15 @@ static int gtalk_newcall(struct gtalk *client, ikspak *pak)
 	}
 
 	/* Now gather all of the codecs that we are asked for */
-	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(p->rtp), &p->peercapability, &peernoncodeccapability);
-	p->jointcapability = p->capability & p->peercapability;
+	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(p->rtp), p->peercap, &peernoncodeccapability);
+	ast_format_cap_joint_copy(p->cap, p->peercap, p->jointcap);
 	ast_mutex_unlock(&p->lock);
 
 	ast_setstate(chan, AST_STATE_RING);
-	if (!p->jointcapability) {
-		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->capability),
-			ast_getformatname_multiple(s2, BUFSIZ, p->peercapability),
-			ast_getformatname_multiple(s3, BUFSIZ, p->jointcapability));
+	if (ast_format_cap_is_empty(p->jointcap)) {
+		ast_log(LOG_WARNING, "Capabilities don't match : us - %s, peer - %s, combined - %s \n", ast_getformatname_multiple(s1, BUFSIZ, p->cap),
+			ast_getformatname_multiple(s2, BUFSIZ, p->peercap),
+			ast_getformatname_multiple(s3, BUFSIZ, p->jointcap));
 		/* close session if capabilities don't match */
 		gtalk_action(client, p, "reject");
 		p->alreadygone = 1;
@@ -1572,12 +1605,12 @@ static struct ast_frame *gtalk_rtp_read(struct ast_channel *ast, struct gtalk_pv
 	if (p->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
-				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
-				p->owner->nativeformats =
-					(p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass.codec;
-				ast_set_read_format(p->owner, p->owner->readformat);
-				ast_set_write_format(p->owner, p->owner->writeformat);
+			if (!ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format)) {
+				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
+				ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
+				ast_set_read_format(p->owner, &p->owner->readformat);
+				ast_set_write_format(p->owner, &p->owner->writeformat);
 			}
 			/* if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
 				f = ast_dsp_process(p->owner, p->vad, f);
@@ -1609,13 +1642,13 @@ static int gtalk_write(struct ast_channel *ast, struct ast_frame *frame)
 
 	switch (frame->frametype) {
 	case AST_FRAME_VOICE:
-		if (!(frame->subclass.codec & ast->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
 			ast_log(LOG_WARNING,
 					"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
-					ast_getformatname(frame->subclass.codec),
+					ast_getformatname(&frame->subclass.format),
 					ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
-					ast_getformatname(ast->readformat),
-					ast_getformatname(ast->writeformat));
+					ast_getformatname(&ast->readformat),
+					ast_getformatname(&ast->writeformat));
 			return 0;
 		}
 		if (p) {
@@ -1845,7 +1878,7 @@ static int gtalk_hangup(struct ast_channel *ast)
 }
 
 /*!\brief Part of PBX interface */
-static struct ast_channel *gtalk_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *gtalk_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct gtalk_pvt *p = NULL;
 	struct gtalk *client = NULL;
@@ -1937,8 +1970,8 @@ static char *gtalk_show_channels(struct ast_cli_entry *e, int cmd, struct ast_cl
 					chan->name,
 					jid,
 					resource,
-					ast_getformatname(chan->readformat),
-					ast_getformatname(chan->writeformat)
+					ast_getformatname(&chan->readformat),
+					ast_getformatname(&chan->writeformat)
 					);
 			else
 				ast_log(LOG_WARNING, "No available channel\n");
@@ -2067,9 +2100,9 @@ static int gtalk_create_member(char *label, struct ast_variable *var, int allowg
 		if (!strcasecmp(var->name, "username"))
 			ast_copy_string(member->user, var->value, sizeof(member->user));
 		else if (!strcasecmp(var->name, "disallow"))
-			ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
+			ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
 		else if (!strcasecmp(var->name, "allow"))
-			ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
+			ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
 		else if (!strcasecmp(var->name, "context"))
 			ast_copy_string(member->context, var->value, sizeof(member->context));
 		else if (!strcasecmp(var->name, "parkinglot"))
@@ -2122,6 +2155,7 @@ static int gtalk_load_config(void)
 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
 
 	/* set defaults */
+	memset(&prefs, 0, sizeof(prefs));
 	memset(&stunaddr, 0, sizeof(stunaddr));
 	global_stunaddr = 0;
 	global_allowguest = DEFAULT_ALLOWGUEST;
@@ -2138,9 +2172,9 @@ static int gtalk_load_config(void)
 		if (!strcasecmp(var->name, "allowguest")) {
 			global_allowguest = (ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
 		} else if (!strcasecmp(var->name, "disallow")) {
-			ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
+			ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
 		} else if (!strcasecmp(var->name, "allow")) {
-			ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
+			ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
 		} else if (!strcasecmp(var->name, "context")) {
 			ast_copy_string(global_context, var->value, sizeof(global_context));
 		} else if (!strcasecmp(var->name, "externip")) {
@@ -2167,6 +2201,7 @@ static int gtalk_load_config(void)
 			member = ast_calloc(1, sizeof(*member));
 			ASTOBJ_INIT(member);
 			ASTOBJ_WRLOCK(member);
+			member->cap = ast_format_cap_alloc_nolock();
 			if (!strcasecmp(cat, "guest")) {
 				ast_copy_string(member->name, "guest", sizeof(member->name));
 				ast_copy_string(member->user, "guest", sizeof(member->user));
@@ -2176,10 +2211,10 @@ static int gtalk_load_config(void)
 				member->prefs = prefs;
 				while (var) {
 					if (!strcasecmp(var->name, "disallow")) {
-						ast_parse_allow_disallow(&member->prefs, &member->capability,
+						ast_parse_allow_disallow(&member->prefs, member->cap,
 												 var->value, 0);
 					} else if (!strcasecmp(var->name, "allow")) {
-						ast_parse_allow_disallow(&member->prefs, &member->capability,
+						ast_parse_allow_disallow(&member->prefs, member->cap,
 												 var->value, 1);
 					} else if (!strcasecmp(var->name, "context")) {
 						ast_copy_string(member->context, var->value,
@@ -2229,8 +2264,22 @@ static int load_module(void)
 {
 	struct ast_sockaddr bindaddr_tmp;
 	struct ast_sockaddr ourip_tmp;
-
 	char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
+	struct ast_format tmpfmt;
+
+	if (!(gtalk_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(global_capability = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_format_cap_add_all_by_type(gtalk_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
+
 	free(jabber_loaded);
 	if (!jabber_loaded) {
 		/* If embedded, check for a different module name */
@@ -2313,6 +2362,8 @@ static int unload_module(void)
 	}
 	ASTOBJ_CONTAINER_DESTROYALL(&gtalk_list, gtalk_member_destroy);
 	ASTOBJ_CONTAINER_DESTROY(&gtalk_list);
+	global_capability = ast_format_cap_destroy(global_capability);
+	gtalk_tech.capabilities = ast_format_cap_destroy(gtalk_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_h323.c b/channels/chan_h323.c
index e549d429907c0e3240607554e8e5cf88a19bdb96..ccc034872c51df067d83e546784c37a6579ad323 100644
--- a/channels/chan_h323.c
+++ b/channels/chan_h323.c
@@ -85,6 +85,8 @@ extern "C" {
 #include "asterisk/stringfields.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/astobj.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
 
 #ifdef __cplusplus
 }
@@ -129,7 +131,13 @@ static const char config[] = "h323.conf";
 static char default_context[AST_MAX_CONTEXT] = "default";
 static struct sockaddr_in bindaddr;
 
-#define GLOBAL_CAPABILITY (AST_FORMAT_G723_1 | AST_FORMAT_GSM | AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_G729A | AST_FORMAT_G726_AAL2 | AST_FORMAT_H261)
+#define GLOBAL_CAPABILITY (ast_format_id_to_old_bitfield(AST_FORMAT_G723_1) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_GSM) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_G729A) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) | \
+	ast_format_id_to_old_bitfield(AST_FORMAT_H261)) \
 
 /** H.323 configuration values */
 static int h323_signalling_port = 1720;
@@ -173,9 +181,9 @@ static struct oh323_pvt {
 	int newcontrol;				/*!< Pending control to send */
 	int newdigit;				/*!< Pending DTMF digit to send */
 	int newduration;			/*!< Pending DTMF digit duration to send */
-	format_t pref_codec;				/*!< Preferred codec */
-	format_t peercapability;			/*!< Capabilities learned from peer */
-	format_t jointcapability;			/*!< Common capabilities for local and remote side */
+	h323_format pref_codec;				/*!< Preferred codec */
+	h323_format peercapability;			/*!< Capabilities learned from peer */
+	h323_format jointcapability;			/*!< Common capabilities for local and remote side */
 	struct ast_codec_pref peer_prefs;	/*!< Preferenced list of codecs which remote side supports */
 	int dtmf_pt[2];				/*!< Payload code used for RFC2833/CISCO messages */
 	int curDTMF;				/*!< DTMF tone being generated to Asterisk side */
@@ -231,7 +239,7 @@ static void delete_users(void);
 static void delete_aliases(void);
 static void prune_peers(void);
 
-static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int oh323_digit_begin(struct ast_channel *c, char digit);
 static int oh323_digit_end(struct ast_channel *c, char digit, unsigned int duration);
 static int oh323_call(struct ast_channel *c, char *dest, int timeout);
@@ -242,10 +250,9 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame);
 static int oh323_indicate(struct ast_channel *c, int condition, const void *data, size_t datalen);
 static int oh323_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 
-static const struct ast_channel_tech oh323_tech = {
+static struct ast_channel_tech oh323_tech = {
 	.type = "H323",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_AUDIO_MASK,
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = oh323_request,
 	.send_digit_begin = oh323_digit_begin,
@@ -331,12 +338,13 @@ static int oh323_simulate_dtmf_end(const void *data)
 /*! \brief Channel and private structures should be already locked */
 static void __oh323_update_info(struct ast_channel *c, struct oh323_pvt *pvt)
 {
-	if (c->nativeformats != pvt->nativeformats) {
+	h323_format chan_nativeformats_bits = ast_format_cap_to_old_bitfield(c->nativeformats);
+	if (chan_nativeformats_bits != pvt->nativeformats) {
 		if (h323debug)
 			ast_debug(1, "Preparing %s for new native format\n", c->name);
-		c->nativeformats = pvt->nativeformats;
-		ast_set_read_format(c, c->readformat);
-		ast_set_write_format(c, c->writeformat);
+		ast_format_cap_from_old_bitfield(c->nativeformats, pvt->nativeformats);
+		ast_set_read_format(c, &c->readformat);
+		ast_set_write_format(c, &c->writeformat);
 	}
 	if (pvt->needhangup) {
 		if (h323debug)
@@ -764,18 +772,20 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
 	if (pvt->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != pvt->owner->nativeformats) {
+			if (!ast_format_cap_iscompatible(pvt->owner->nativeformats, &f->subclass.format)) {
 				/* Try to avoid deadlock */
 				if (ast_channel_trylock(pvt->owner)) {
 					ast_log(LOG_NOTICE, "Format changed but channel is locked. Ignoring frame...\n");
 					return &ast_null_frame;
 				}
 				if (h323debug)
-					ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(f->subclass.codec));
-				pvt->owner->nativeformats = f->subclass.codec;
-				pvt->nativeformats = f->subclass.codec;
-				ast_set_read_format(pvt->owner, pvt->owner->readformat);
-				ast_set_write_format(pvt->owner, pvt->owner->writeformat);
+					ast_debug(1, "Oooh, format changed to '%s'\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_set(pvt->owner->nativeformats, &f->subclass.format);
+
+				pvt->nativeformats = ast_format_to_old_bitfield(&f->subclass.format);
+
+				ast_set_read_format(pvt->owner, &pvt->owner->readformat);
+				ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
 				ast_channel_unlock(pvt->owner);
 			}
 			/* Do in-band DTMF detection */
@@ -788,7 +798,7 @@ static struct ast_frame *oh323_rtp_read(struct oh323_pvt *pvt)
 					else
 						ast_log(LOG_NOTICE, "Unable to process inband DTMF while channel is locked\n");
 				} else if (pvt->nativeformats && !pvt->noInbandDtmf) {
-					ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(f->subclass.codec));
+					ast_log(LOG_NOTICE, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(&f->subclass.format));
 					pvt->noInbandDtmf = 1;
 				}
 				if (f &&(f->frametype == AST_FRAME_DTMF)) {
@@ -838,10 +848,10 @@ static int oh323_write(struct ast_channel *c, struct ast_frame *frame)
 			return 0;
 		}
 	} else {
-		if (!(frame->subclass.codec & c->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(c->nativeformats, &frame->subclass.format))) {
 			char tmp[256];
 			ast_log(LOG_WARNING, "Asked to transmit frame type '%s', while native formats is '%s' (read/write = %s/%s)\n",
-				ast_getformatname(frame->subclass.codec), ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname(c->readformat), ast_getformatname(c->writeformat));
+				ast_getformatname(&frame->subclass.format), ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname(&c->readformat), ast_getformatname(&c->writeformat));
 			return 0;
 		}
 	}
@@ -1011,7 +1021,8 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
 {
 	struct ast_channel *ch;
 	char *cid_num, *cid_name;
-	int fmt;
+	h323_format fmt;
+	struct ast_format tmpfmt;
 
 	if (!ast_strlen_zero(pvt->options.cid_num))
 		cid_num = pvt->options.cid_num;
@@ -1033,13 +1044,18 @@ static struct ast_channel *__oh323_new(struct oh323_pvt *pvt, int state, const c
 		ch->tech = &oh323_tech;
 		if (!(fmt = pvt->jointcapability) && !(fmt = pvt->options.capability))
 			fmt = global_options.capability;
-		ch->nativeformats = ast_codec_choose(&pvt->options.prefs, fmt, 1)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
-		pvt->nativeformats = ch->nativeformats;
-		fmt = ast_best_codec(ch->nativeformats);
-		ch->writeformat = fmt;
-		ch->rawwriteformat = fmt;
-		ch->readformat = fmt;
-		ch->rawreadformat = fmt;
+
+		ast_format_cap_from_old_bitfield(ch->nativeformats, fmt);
+		ast_codec_choose(&pvt->options.prefs, ch->nativeformats, 1, &tmpfmt)/* | (pvt->jointcapability & AST_FORMAT_VIDEO_MASK)*/;
+
+		ast_format_cap_set(ch->nativeformats, &tmpfmt);
+
+		pvt->nativeformats = ast_format_cap_to_old_bitfield(ch->nativeformats);
+		ast_best_codec(ch->nativeformats, &tmpfmt);
+		ast_format_copy(&ch->writeformat, &tmpfmt);
+		ast_format_copy(&ch->rawwriteformat, &tmpfmt);
+		ast_format_copy(&ch->readformat, &tmpfmt);
+		ast_format_copy(&ch->rawreadformat, &tmpfmt);
 		if (!pvt->rtp)
 			__oh323_rtp_create(pvt);
 #if 0
@@ -1264,17 +1280,33 @@ static struct oh323_alias *realtime_alias(const char *alias)
 	return a;
 }
 
+static int h323_parse_allow_disallow(struct ast_codec_pref *pref, h323_format *formats, const char *list, int allowing)
+{
+	int res;
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
+		return 1;
+	}
+
+	ast_format_cap_from_old_bitfield(cap, *formats);
+	res = ast_parse_allow_disallow(pref, cap, list, allowing);
+	*formats = ast_format_cap_to_old_bitfield(cap);
+	cap = ast_format_cap_destroy(cap);
+	return res;
+
+}
+
 static int update_common_options(struct ast_variable *v, struct call_options *options)
 {
 	int tmp = 0;
 	char *val, *opt;
 
 	if (!strcasecmp(v->name, "allow")) {
-		ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
+		h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 1);
 	} else if (!strcasecmp(v->name, "autoframing")) {
 		options->autoframing = ast_true(v->value);
 	} else if (!strcasecmp(v->name, "disallow")) {
-		ast_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
+		h323_parse_allow_disallow(&options->prefs, &options->capability, v->value, 0);
 	} else if (!strcasecmp(v->name, "dtmfmode")) {
 		val = ast_strdupa(v->value);
 		if ((opt = strchr(val, ':')) != (char *)NULL) {
@@ -1745,9 +1777,8 @@ static int create_addr(struct oh323_pvt *pvt, char *opeer)
 		return 0;
 	}
 }
-static struct ast_channel *oh323_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *oh323_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat;
 	struct oh323_pvt *pvt;
 	struct ast_channel *tmpc = NULL;
 	char *dest = (char *)data;
@@ -1756,17 +1787,15 @@ static struct ast_channel *oh323_request(const char *type, format_t format, cons
 	char tmp[256], tmp1[256];
 
 	if (h323debug)
-		ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), format), (char *)data);
+		ast_debug(1, "type=%s, format=%s, data=%s.\n", type, ast_getformatname_multiple(tmp, sizeof(tmp), cap), (char *)data);
 
 	pvt = oh323_alloc(0);
 	if (!pvt) {
 		ast_log(LOG_WARNING, "Unable to build pvt data for '%s'\n", (char *)data);
 		return NULL;
 	}
-	oldformat = format;
-	format &= AST_FORMAT_AUDIO_MASK;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
+	if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		oh323_destroy(pvt);
 		if (cause)
 			*cause = AST_CAUSE_INCOMPATIBLE_DESTINATION;
@@ -2020,11 +2049,11 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
 	nativeformats_changed = 0;
 	if (pt != 128 && pvt->rtp) {	/* Payload type is invalid, so try to use previously decided */
 		struct ast_rtp_payload_type rtptype = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(pvt->rtp), pt);
-		if (h323debug)
-			ast_debug(1, "Native format is set to %llu from %d by RTP payload type %d\n", (unsigned long long) rtptype.code, pvt->nativeformats, pt);
-		if (pvt->nativeformats != rtptype.code) {
-			pvt->nativeformats = rtptype.code;
-			nativeformats_changed = 1;
+		if (rtptype.asterisk_format) {
+			if (pvt->nativeformats != ast_format_to_old_bitfield(&rtptype.format)) {
+				pvt->nativeformats = ast_format_to_old_bitfield(&rtptype.format);
+				nativeformats_changed = 1;
+			}
 		}
 	} else if (h323debug)
 		ast_log(LOG_NOTICE, "Payload type is unknown, formats isn't changed\n");
@@ -2032,15 +2061,18 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
 	/* Don't try to lock the channel if nothing changed */
 	if (nativeformats_changed || pvt->options.progress_audio || (rtp_change != NEED_NONE)) {
 		if (pvt->owner && !ast_channel_trylock(pvt->owner)) {
+			struct ast_format_cap *pvt_native = ast_format_cap_alloc_nolock();
+			ast_format_cap_from_old_bitfield(pvt_native, pvt->nativeformats);
+
 			/* Re-build translation path only if native format(s) has been changed */
-			if (pvt->owner->nativeformats != pvt->nativeformats) {
+			if (!(ast_format_cap_identical(pvt->owner->nativeformats, pvt_native))) {
 				if (h323debug) {
 					char tmp[256], tmp2[256];
-					ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(pvt->owner->readformat), ast_getformatname(pvt->owner->writeformat));
+					ast_debug(1, "Native format changed to '%s' from '%s', read format is %s, write format is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), pvt_native), ast_getformatname_multiple(tmp2, sizeof(tmp2), pvt->owner->nativeformats), ast_getformatname(&pvt->owner->readformat), ast_getformatname(&pvt->owner->writeformat));
 				}
-				pvt->owner->nativeformats = pvt->nativeformats;
-				ast_set_read_format(pvt->owner, pvt->owner->readformat);
-				ast_set_write_format(pvt->owner, pvt->owner->writeformat);
+				ast_format_cap_copy(pvt->owner->nativeformats, pvt_native);
+				ast_set_read_format(pvt->owner, &pvt->owner->readformat);
+				ast_set_write_format(pvt->owner, &pvt->owner->writeformat);
 			}
 			if (pvt->options.progress_audio)
 				ast_queue_control(pvt->owner, AST_CONTROL_PROGRESS);
@@ -2055,6 +2087,7 @@ static void setup_rtp_connection(unsigned call_reference, const char *remoteIp,
 				break;
 			}
 			ast_channel_unlock(pvt->owner);
+			pvt_native = ast_format_cap_destroy(pvt_native);
 		}
 		else {
 			if (pvt->options.progress_audio)
@@ -2491,7 +2524,7 @@ static void set_peer_capabilities(unsigned call_reference, const char *token, in
 			for (i = 0; i < 32; ++i) {
 				if (!prefs->order[i])
 					break;
-				ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(1 << (prefs->order[i]-1)) : "<none>"), prefs->framing[i]);
+				ast_debug(1, "prefs[%d]=%s:%d\n", i, (prefs->order[i] ? ast_getformatname(&prefs->formats[i]) : "<none>"), prefs->framing[i]);
 			}
 		}
 		if (pvt->rtp) {
@@ -2531,7 +2564,7 @@ static void set_local_capabilities(unsigned call_reference, const char *token)
 		for (i = 0; i < 32; i++) {
 			if (!prefs.order[i])
 				break;
-			ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(1 << (prefs.order[i]-1)) : "<none>"), prefs.framing[i]);
+			ast_debug(1, "local prefs[%d]=%s:%d\n", i, (prefs.order[i] ? ast_getformatname(&prefs.formats[i]) : "<none>"), prefs.framing[i]);
 		}
 		ast_debug(1, "Capabilities for connection %s is set\n", token);
 	}
@@ -3191,9 +3224,9 @@ static enum ast_rtp_glue_result oh323_get_rtp_peer(struct ast_channel *chan, str
 	return res;
 }
 
-static char *convertcap(format_t cap)
+static char *convertcap(struct ast_format *format)
 {
-	switch (cap) {
+	switch (format->id) {
 	case AST_FORMAT_G723_1:
 		return "G.723";
 	case AST_FORMAT_GSM:
@@ -3213,12 +3246,12 @@ static char *convertcap(format_t cap)
 	case AST_FORMAT_ILBC:
 		return "ILBC";
 	default:
-		ast_log(LOG_NOTICE, "Don't know how to deal with mode %" PRId64 "\n", cap);
+		ast_log(LOG_NOTICE, "Don't know how to deal with mode %s\n", ast_getformatname(format));
 		return NULL;
 	}
 }
 
-static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
 {
 	/* XXX Deal with Video */
 	struct oh323_pvt *pvt;
@@ -3230,7 +3263,7 @@ static int oh323_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance
 		return 0;
 	}
 
-	mode = convertcap(chan->writeformat);
+	mode = convertcap(&chan->writeformat);
 	pvt = (struct oh323_pvt *) chan->tech_pvt;
 	if (!pvt) {
 		ast_log(LOG_ERROR, "No Private Structure, this is bad\n");
@@ -3260,6 +3293,11 @@ static enum ast_module_load_result load_module(void)
 {
 	int res;
 
+	if (!(oh323_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add_all_by_type(oh323_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+
 	h323debug = 0;
 	sched = ast_sched_context_create();
 	if (!sched) {
@@ -3430,6 +3468,7 @@ static int unload_module(void)
 	ASTOBJ_CONTAINER_DESTROYALL(&aliasl, oh323_destroy_alias);
 	ASTOBJ_CONTAINER_DESTROY(&aliasl);
 
+	oh323_tech.capabilities = ast_format_cap_destroy(oh323_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 5de2c4a23a2c76be345bd75ae32230e460b7562e..49434d6785274e302e8904091dcdc6379d64c7e7 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -317,22 +317,22 @@ static int (*iax2_regfunk)(const char *username, int onoff) = NULL;
 #define IAX_CAPABILITY_FULLBANDWIDTH	0xFFFF
 /* T1, maybe ISDN */
 #define IAX_CAPABILITY_MEDBANDWIDTH (IAX_CAPABILITY_FULLBANDWIDTH & \
-                     ~AST_FORMAT_SLINEAR &      \
-                     ~AST_FORMAT_SLINEAR16 &    \
-                     ~AST_FORMAT_SIREN7 &       \
-                     ~AST_FORMAT_SIREN14 &      \
-                     ~AST_FORMAT_G719 &         \
-                     ~AST_FORMAT_ULAW &         \
-                     ~AST_FORMAT_ALAW &         \
-                     ~AST_FORMAT_G722)
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR) &      \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_SLINEAR16) &    \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN7) &       \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_SIREN14) &      \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_G719) &         \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_ULAW) &         \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_ALAW) &         \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_G722))
 /* A modem */
 #define IAX_CAPABILITY_LOWBANDWIDTH (IAX_CAPABILITY_MEDBANDWIDTH & \
-                     ~AST_FORMAT_G726 &         \
-                     ~AST_FORMAT_G726_AAL2 &    \
-                     ~AST_FORMAT_ADPCM)
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_G726) &         \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_G726_AAL2) &    \
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_ADPCM))
 
 #define IAX_CAPABILITY_LOWFREE      (IAX_CAPABILITY_LOWBANDWIDTH & \
-                     ~AST_FORMAT_G723_1)
+                     ~ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))
 
 
 #define DEFAULT_MAXMS		2000		/* Must be faster than 2 seconds by default */
@@ -361,7 +361,7 @@ static struct ast_sched_context *sched;
 
 #define DONT_RESCHEDULE -2
 
-static format_t iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
+static iax2_format iax2_capability = IAX_CAPABILITY_FULLBANDWIDTH;
 
 static int iaxdebug = 0;
 
@@ -470,7 +470,7 @@ struct iax2_user {
 	int amaflags;
 	int adsi;
 	uint64_t flags;
-	format_t capability;
+	iax2_format capability;
 	int maxauthreq; /*!< Maximum allowed outstanding AUTHREQs */
 	int curauthreq; /*!< Current number of outstanding AUTHREQs */
 	struct ast_codec_pref prefs;
@@ -517,7 +517,7 @@ struct iax2_peer {
 
 	int expire;					/*!< Schedule entry for expiry */
 	int expiry;					/*!< How soon to expire */
-	format_t capability;        /*!< Capability */
+	iax2_format capability;        /*!< Capability */
 
 	/* Qualification */
 	int callno;					/*!< Call number of POKE request */
@@ -648,15 +648,15 @@ struct chan_iax2_pvt {
 	/*! Socket to send/receive on for this call */
 	int sockfd;
 	/*! Last received voice format */
-	format_t voiceformat;
+	iax2_format voiceformat;
 	/*! Last received video format */
-	format_t videoformat;
+	iax2_format videoformat;
 	/*! Last sent voice format */
-	format_t svoiceformat;
+	iax2_format svoiceformat;
 	/*! Last sent video format */
-	format_t svideoformat;
+	iax2_format svideoformat;
 	/*! What we are capable of sending */
-	format_t capability;
+	iax2_format capability;
 	/*! Last received timestamp */
 	unsigned int last;
 	/*! Last sent timestamp - never send the same timestamp twice in a single call */
@@ -690,11 +690,11 @@ struct chan_iax2_pvt {
 	/*! Negotiated format, this is only used to remember what format was
 	    chosen for an unauthenticated call so that the channel can get
 	    created later using the right format */
-	format_t chosenformat;
+	iax2_format chosenformat;
 	/*! Peer selected format */
-	format_t peerformat;
+	iax2_format peerformat;
 	/*! Peer capability */
-	format_t peercapability;
+	iax2_format peercapability;
 	/*! timeval that we base our transmission on */
 	struct timeval offset;
 	/*! timeval that we base our delivery on */
@@ -1191,7 +1191,7 @@ static int send_command_final(struct chan_iax2_pvt *, char, int, unsigned int, c
 static int send_command_immediate(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int, int);
 static int send_command_locked(unsigned short callno, char, int, unsigned int, const unsigned char *, int, int);
 static int send_command_transfer(struct chan_iax2_pvt *, char, int, unsigned int, const unsigned char *, int);
-static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static struct ast_frame *iax2_read(struct ast_channel *c);
 static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
 static struct iax2_user *build_user(const char *name, struct ast_variable *v, struct ast_variable *alt, int temponly);
@@ -1211,10 +1211,9 @@ static int replace_callno(const void *obj);
 static void sched_delay_remove(struct sockaddr_in *sin, struct callno_entry *callno_entry);
 static void network_change_event_cb(const struct ast_event *, void *);
 
-static const struct ast_channel_tech iax2_tech = {
+static struct ast_channel_tech iax2_tech = {
 	.type = "IAX2",
 	.description = tdesc,
-	.capabilities = IAX_CAPABILITY_FULLBANDWIDTH,
 	.properties = AST_CHAN_TP_WANTSJITTER,
 	.requester = iax2_request,
 	.devicestate = iax2_devicestate,
@@ -1604,7 +1603,7 @@ static int send_lagrq(const void *data)
 	return 0;
 }
 
-static unsigned char compress_subclass(format_t subclass)
+static unsigned char compress_subclass(iax2_format subclass)
 {
 	int x;
 	int power=-1;
@@ -1624,7 +1623,7 @@ static unsigned char compress_subclass(format_t subclass)
 	return power | IAX_FLAG_SC_LOG;
 }
 
-static format_t uncompress_subclass(unsigned char csub)
+static iax2_format uncompress_subclass(unsigned char csub)
 {
 	/* If the SC_LOG flag is set, return 2^csub otherwise csub */
 	if (csub & IAX_FLAG_SC_LOG) {
@@ -1638,6 +1637,90 @@ static format_t uncompress_subclass(unsigned char csub)
 		return csub;
 }
 
+static iax2_format iax2_codec_choose(struct ast_codec_pref *pref, iax2_format formats, int find_best)
+{
+	struct ast_format_cap *cap;
+	struct ast_format tmpfmt;
+	iax2_format format = 0;
+	if ((cap = ast_format_cap_alloc_nolock())) {
+		ast_format_clear(&tmpfmt);
+		ast_format_cap_from_old_bitfield(cap, formats);
+		ast_codec_choose(pref, cap, find_best, &tmpfmt);
+		format = ast_format_to_old_bitfield(&tmpfmt);
+		cap = ast_format_cap_destroy(cap);
+	}
+
+	return format;
+}
+
+static iax2_format iax2_best_codec(iax2_format formats)
+{
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	struct ast_format tmpfmt;
+	if (!cap) {
+		return 0;
+	}
+
+	ast_format_clear(&tmpfmt);
+	ast_format_cap_from_old_bitfield(cap, formats);
+	ast_best_codec(cap, &tmpfmt);
+	cap = ast_format_cap_destroy(cap);
+	return ast_format_to_old_bitfield(&tmpfmt);
+}
+
+char *iax2_getformatname(iax2_format format)
+{
+	struct ast_format tmpfmt;
+	if (!(ast_format_from_old_bitfield(&tmpfmt, format))) {
+		return "Unknown";
+	}
+
+	return ast_getformatname(&tmpfmt);
+}
+
+static char *iax2_getformatname_multiple(char *codec_buf, size_t len, iax2_format format)
+{
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+
+	if (!cap) {
+		return "(Nothing)";
+	}
+	ast_format_cap_from_old_bitfield(cap, format);
+	ast_getformatname_multiple(codec_buf, len, cap);
+	cap = ast_format_cap_destroy(cap);
+
+	return codec_buf;
+}
+
+static int iax2_parse_allow_disallow(struct ast_codec_pref *pref, iax2_format *formats, const char *list, int allowing)
+{
+	int res;
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
+		return 1;
+	}
+
+	ast_format_cap_from_old_bitfield(cap, *formats);
+	res = ast_parse_allow_disallow(pref, cap, list, allowing);
+	*formats = ast_format_cap_to_old_bitfield(cap);
+	cap = ast_format_cap_destroy(cap);
+
+	return res;
+}
+
+static int iax2_data_add_codecs(struct ast_data *root, const char *node_name, iax2_format formats)
+{
+	int res;
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
+		return -1;
+	}
+	ast_format_cap_from_old_bitfield(cap, formats);
+	res = ast_data_add_codecs(root, node_name, cap);
+	cap = ast_format_cap_destroy(cap);
+	return res;
+}
+
 /*!
  * \note The only member of the peer passed here guaranteed to be set is the name field
  */
@@ -3727,7 +3810,7 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
 	struct iax2_peer *peer;
 	char codec_buf[512];
 	struct ast_str *encmethods = ast_str_alloca(256);
-	int x = 0, codec = 0, load_realtime = 0;
+	int x = 0, load_realtime = 0;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -3772,16 +3855,16 @@ static char *handle_cli_iax2_show_peer(struct ast_cli_entry *e, int cmd, struct
 		ast_cli(a->fd, "  Defaddr->IP  : %s Port %d\n", ast_inet_ntoa(peer->defaddr.sin_addr), ntohs(peer->defaddr.sin_port));
 		ast_cli(a->fd, "  Username     : %s\n", peer->username);
 		ast_cli(a->fd, "  Codecs       : ");
-		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
+		iax2_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
 		ast_cli(a->fd, "%s\n", codec_buf);
 
 		ast_cli(a->fd, "  Codec Order  : (");
-		for(x = 0; x < 32 ; x++) {
-			codec = ast_codec_pref_index(&peer->prefs,x);
-			if(!codec)
+		for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+			struct ast_format tmpfmt;
+			if(!(ast_codec_pref_index(&peer->prefs, x, &tmpfmt)))
 				break;
-			ast_cli(a->fd, "%s", ast_getformatname(codec));
-			if(x < 31 && ast_codec_pref_index(&peer->prefs,x+1))
+			ast_cli(a->fd, "%s", ast_getformatname(&tmpfmt));
+			if(x < 31 && ast_codec_pref_index(&peer->prefs, x+1, &tmpfmt))
 				ast_cli(a->fd, "|");
 		}
 
@@ -4067,7 +4150,9 @@ static void __get_from_jb(const void *p)
 	ms = ast_tvdiff_ms(now, pvt->rxcore);
 	
 	if(ms >= (next = jb_next(pvt->jb))) {
-		ret = jb_get(pvt->jb,&frame,ms,ast_codec_interp_len(pvt->voiceformat));
+		struct ast_format voicefmt;
+		ast_format_from_old_bitfield(&voicefmt, pvt->voiceformat);
+		ret = jb_get(pvt->jb, &frame, ms, ast_codec_interp_len(&voicefmt));
 		switch(ret) {
 		case JB_OK:
 			fr = frame.data;
@@ -4081,8 +4166,8 @@ static void __get_from_jb(const void *p)
 			
 			/* create an interpolation frame */
 			af.frametype = AST_FRAME_VOICE;
-			af.subclass.codec = pvt->voiceformat;
-			af.samples  = frame.ms * (ast_format_rate(pvt->voiceformat) / 1000);
+			ast_format_copy(&af.subclass.format, &voicefmt);
+			af.samples  = frame.ms * (ast_format_rate(&voicefmt) / 1000);
 			af.src  = "IAX2 JB interpolation";
 			af.delivery = ast_tvadd(pvt->rxcore, ast_samp2tv(next, 1000));
 			af.offset = AST_FRIENDLY_OFFSET;
@@ -4154,7 +4239,7 @@ static int schedule_delivery(struct iax_frame *fr, int updatehistory, int fromtr
 
 	if(fr->af.frametype == AST_FRAME_VOICE) {
 		type = JB_TYPE_VOICE;
-		len = ast_codec_get_samples(&fr->af) / (ast_format_rate(fr->af.subclass.codec) / 1000);
+		len = ast_codec_get_samples(&fr->af) / (ast_format_rate(&fr->af.subclass.format) / 1000);
 	} else if(fr->af.frametype == AST_FRAME_CNG) {
 		type = JB_TYPE_SILENCE;
 	}
@@ -4511,7 +4596,7 @@ static void realtime_update_peer(const char *peername, struct ast_sockaddr *sock
 }
 
 struct create_addr_info {
-	format_t capability;
+	iax2_format capability;
 	uint64_t flags;
 	int maxtime;
 	int encmethods;
@@ -4557,8 +4642,14 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
 		/* use global iax prefs for unknown peer/user */
 		/* But move the calling channel's native codec to the top of the preference list */
 		memcpy(&ourprefs, &prefs, sizeof(ourprefs));
-		if (c)
-			ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+		if (c) {
+			struct ast_format tmpfmt;
+			ast_format_cap_iter_start(c->nativeformats);
+			while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
+				ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+			}
+			ast_format_cap_iter_end(c->nativeformats);
+		}
 		ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 		return 0;
 	}
@@ -4585,8 +4676,13 @@ static int create_addr(const char *peername, struct ast_channel *c, struct socka
 	memcpy(&ourprefs, &peer->prefs, sizeof(ourprefs));
 	/* Move the calling channel's native codec to the top of the preference list */
 	if (c) {
-		ast_debug(1, "prepending %llx to prefs\n", (unsigned long long) c->nativeformats);
-		ast_codec_pref_prepend(&ourprefs, c->nativeformats, 1);
+		struct ast_format tmpfmt;
+		ast_format_cap_iter_start(c->nativeformats);
+		while (!(ast_format_cap_iter_next(c->nativeformats, &tmpfmt))) {
+			ast_debug(1, "prepending %s to prefs\n", ast_getformatname(&tmpfmt));
+			ast_codec_pref_prepend(&ourprefs, &tmpfmt, 1);
+		}
+		ast_format_cap_iter_end(c->nativeformats);
 	}
 	ast_codec_pref_convert(&ourprefs, cai->prefs, sizeof(cai->prefs), 1);
 	ast_copy_string(cai->context, peer->context, sizeof(cai->context));
@@ -4995,6 +5091,7 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
 	unsigned char osp_block_index;
 	unsigned int osp_block_length;
 	unsigned char osp_buffer[256];
+	iax2_format iax2_tmpfmt;
 
 	if ((c->_state != AST_STATE_DOWN) && (c->_state != AST_STATE_RESERVED)) {
 		ast_log(LOG_WARNING, "Channel is already in use (%s)?\n", c->name);
@@ -5121,8 +5218,10 @@ static int iax2_call(struct ast_channel *c, char *dest, int timeout)
 	if (pds.password)
 		ast_string_field_set(iaxs[callno], secret, pds.password);
 
-	iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) c->nativeformats);
-	iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, c->nativeformats);
+	iax2_tmpfmt = ast_format_cap_to_old_bitfield(c->nativeformats);
+	iax_ie_append_int(&ied, IAX_IE_FORMAT, (int) iax2_tmpfmt);
+	iax_ie_append_versioned_uint64(&ied, IAX_IE_FORMAT2, 0, iax2_tmpfmt);
+
 	iax_ie_append_int(&ied, IAX_IE_CAPABILITY, (int) iaxs[callno]->capability);
 	iax_ie_append_versioned_uint64(&ied, IAX_IE_CAPABILITY2, 0, iaxs[callno]->capability);
 	iax_ie_append_short(&ied, IAX_IE_ADSICPE, c->adsicpe);
@@ -5471,7 +5570,7 @@ static enum ast_bridge_result iax2_bridge(struct ast_channel *c0, struct ast_cha
 			}
 			return AST_BRIDGE_FAILED_NOWARN;
 		}
-		if (c0->nativeformats != c1->nativeformats) {
+		if (!(ast_format_cap_identical(c0->nativeformats, c1->nativeformats))) {
 			char buf0[256];
 			char buf1[256];
 			ast_getformatname_multiple(buf0, sizeof(buf0), c0->nativeformats);
@@ -5676,11 +5775,12 @@ static int iax2_getpeertrunk(struct sockaddr_in sin)
 }
 
 /*! \brief  Create new call, interface with the PBX core */
-static struct ast_channel *ast_iax2_new(int callno, int state, format_t capability, const char *linkedid)
+static struct ast_channel *ast_iax2_new(int callno, int state, iax2_format capability, const char *linkedid)
 {
 	struct ast_channel *tmp;
 	struct chan_iax2_pvt *i;
 	struct ast_variable *v = NULL;
+	struct ast_format tmpfmt;
 
 	if (!(i = iaxs[callno])) {
 		ast_log(LOG_WARNING, "No IAX2 pvt found for callno '%d' !\n", callno);
@@ -5705,9 +5805,14 @@ static struct ast_channel *ast_iax2_new(int callno, int state, format_t capabili
 		return NULL;
 	tmp->tech = &iax2_tech;
 	/* We can support any format by default, until we get restricted */
-	tmp->nativeformats = capability;
-	tmp->readformat = tmp->rawreadformat = ast_best_codec(capability);
-	tmp->writeformat = tmp->rawwriteformat = ast_best_codec(capability);
+	ast_format_cap_from_old_bitfield(tmp->nativeformats, capability);
+	ast_best_codec(tmp->nativeformats, &tmpfmt);
+
+	ast_format_copy(&tmp->readformat, &tmpfmt);
+	ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+	ast_format_copy(&tmp->writeformat, &tmpfmt);
+	ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+
 	tmp->tech_pvt = CALLNO_TO_PTR(i->callno);
 
 	if (!ast_strlen_zero(i->parkinglot))
@@ -5848,7 +5953,7 @@ static unsigned int calc_timestamp(struct chan_iax2_pvt *p, unsigned int ts, str
 	int voice = 0;
 	int genuine = 0;
 	int adjust;
-	int rate = ast_format_rate(f->subclass.codec) / 1000;
+	int rate = ast_format_rate(&f->subclass.format) / 1000;
 	struct timeval *delivery = NULL;
 
 
@@ -6221,9 +6326,9 @@ static int decode_frame(ast_aes_decrypt_key *dcx, struct ast_iax2_full_hdr *fh,
 		memcpy(efh->encdata, workspace + padding, *datalen - sizeof(struct ast_iax2_full_enc_hdr));
 		f->frametype = fh->type;
 		if (f->frametype == AST_FRAME_VIDEO) {
-			f->subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
+			ast_format_from_old_bitfield(&f->subclass.format, (uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1)));
 		} else if (f->frametype == AST_FRAME_VOICE) {
-			f->subclass.codec = uncompress_subclass(fh->csub);
+			ast_format_from_old_bitfield(&f->subclass.format, uncompress_subclass(fh->csub));
 		} else {
 			f->subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -6366,7 +6471,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 		/* High two bytes are the same on timestamp, or sending on a trunk */ &&
 	    (f->frametype == AST_FRAME_VOICE) 
 		/* is a voice frame */ &&
-		(f->subclass.codec == pvt->svoiceformat) 
+		(f->subclass.format.id == ast_format_id_from_old_bitfield(pvt->svoiceformat))
 		/* is the same type */ ) {
 			/* Force immediate rather than delayed transmission */
 			now = 1;
@@ -6380,7 +6485,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 		 * Otherwise send a mini video frame
 		 */
 		if (((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) &&
-		    ((f->subclass.codec & ~0x1LL) == pvt->svideoformat)
+		    ((f->subclass.format.id) == ast_format_id_from_old_bitfield(pvt->svideoformat))
 		   ) {
 			now = 1;
 			sendmini = 1;
@@ -6435,9 +6540,11 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 		fh->type = fr->af.frametype & 0xFF;
 
 		if (fr->af.frametype == AST_FRAME_VIDEO) {
-			fh->csub = compress_subclass(fr->af.subclass.codec & ~0x1LL) | ((fr->af.subclass.codec & 0x1LL) << 6);
+			iax2_format tmpfmt = ast_format_to_old_bitfield(&fr->af.subclass.format);
+			tmpfmt |= ast_format_get_video_mark(&fr->af.subclass.format) ? 0x1LL : 0;
+			fh->csub = compress_subclass(tmpfmt | ((tmpfmt & 0x1LL) << 6));
 		} else if (fr->af.frametype == AST_FRAME_VOICE) {
-			fh->csub = compress_subclass(fr->af.subclass.codec);
+			fh->csub = compress_subclass(ast_format_to_old_bitfield(&fr->af.subclass.format));
 		} else {
 			fh->csub = compress_subclass(fr->af.subclass.integer);
 		}
@@ -6460,9 +6567,9 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 		if ((f->frametype == AST_FRAME_IAX) && (f->subclass.integer == IAX_COMMAND_ACK))
 			fr->retries = -1;
 		else if (f->frametype == AST_FRAME_VOICE)
-			pvt->svoiceformat = f->subclass.codec;
+			pvt->svoiceformat = ast_format_to_old_bitfield(&f->subclass.format);
 		else if (f->frametype == AST_FRAME_VIDEO)
-			pvt->svideoformat = f->subclass.codec & ~0x1LL;
+			pvt->svideoformat = ast_format_to_old_bitfield(&f->subclass.format);
 		if (ast_test_flag64(pvt, IAX_ENCRYPTED)) {
 			if (ast_test_flag64(pvt, IAX_KEYPOPULATED)) {
 				if (fr->transfer)
@@ -6493,7 +6600,7 @@ static int iax2_send(struct chan_iax2_pvt *pvt, struct ast_frame *f, unsigned in
 			vh = (struct ast_iax2_video_hdr *)(fr->af.data.ptr - sizeof(struct ast_iax2_video_hdr));
 			vh->zeros = 0;
 			vh->callno = htons(0x8000 | fr->callno);
-			vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass.codec & 0x1LL ? 0x8000 : 0));
+			vh->ts = htons((fr->ts & 0x7FFF) | (ast_format_get_video_mark(&fr->af.subclass.format) ? 0x8000 : 0));
 			fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr);
 			fr->data = vh;
 			fr->retries = -1;
@@ -7167,7 +7274,7 @@ static char *handle_cli_iax2_show_channels(struct ast_cli_entry *e, int cmd, str
 				lag,
 				jitter,
 				localdelay,
-				ast_getformatname(iaxs[x]->voiceformat),
+				iax2_getformatname(iaxs[x]->voiceformat),
 				(iaxs[x]->first_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
 				first_message,
 				(iaxs[x]->last_iax_message & MARK_IAX_SUBCLASS_TX) ? "Tx:" : "Rx:",
@@ -9659,7 +9766,7 @@ static int socket_process_meta(int packet_len, struct ast_iax2_meta_hdr *meta, s
 			ast_log(LOG_WARNING, "Received trunked frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
 		} else {
-			f.subclass.codec = iaxs[fr->callno]->voiceformat;
+			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
 			f.datalen = len;
 			if (f.datalen >= 0) {
 				if (f.datalen)
@@ -9806,7 +9913,7 @@ static int socket_process(struct iax2_thread *thread)
 	struct iax2_peer *peer;
 	struct iax_ies ies;
 	struct iax_ie_data ied0, ied1;
-	format_t format;
+	iax2_format format;
 	int fd;
 	int exists;
 	int minivid = 0;
@@ -9877,9 +9984,12 @@ static int socket_process(struct iax2_thread *thread)
 		/* Retrieve the type and subclass */
 		f.frametype = fh->type;
 		if (f.frametype == AST_FRAME_VIDEO) {
-			f.subclass.codec = uncompress_subclass(fh->csub & ~0x40) | ((fh->csub >> 6) & 0x1);
+			ast_format_from_old_bitfield(&f.subclass.format, (uncompress_subclass(fh->csub & ~0x40)));
+			if ((fh->csub >> 6) & 0x1) {
+				ast_format_set_video_mark(&f.subclass.format);
+			}
 		} else if (f.frametype == AST_FRAME_VOICE) {
-			f.subclass.codec = uncompress_subclass(fh->csub);
+			ast_format_from_old_bitfield(&f.subclass.format, uncompress_subclass(fh->csub));
 		} else {
 			f.subclass.integer = uncompress_subclass(fh->csub);
 		}
@@ -10250,21 +10360,24 @@ static int socket_process(struct iax2_thread *thread)
 		}
 
 		if (f.frametype == AST_FRAME_VOICE) {
-			if (f.subclass.codec != iaxs[fr->callno]->voiceformat) {
-					iaxs[fr->callno]->voiceformat = f.subclass.codec;
-					ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(f.subclass.codec));
+			if (ast_format_to_old_bitfield(&f.subclass.format) != iaxs[fr->callno]->voiceformat) {
+					iaxs[fr->callno]->voiceformat = ast_format_to_old_bitfield(&f.subclass.format);
+					ast_debug(1, "Ooh, voice format changed to '%s'\n", ast_getformatname(&f.subclass.format));
 					if (iaxs[fr->callno]->owner) {
 						iax2_lock_owner(fr->callno);
 						if (iaxs[fr->callno]) {
 							if (iaxs[fr->callno]->owner) {
-								format_t orignative;
-
-								orignative = iaxs[fr->callno]->owner->nativeformats;
-								iaxs[fr->callno]->owner->nativeformats = f.subclass.codec;
-								if (iaxs[fr->callno]->owner->readformat)
-									ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);
-								iaxs[fr->callno]->owner->nativeformats = orignative;
-								ast_channel_unlock(iaxs[fr->callno]->owner);
+								struct ast_format_cap *orignative = ast_format_cap_dup(iaxs[fr->callno]->owner->nativeformats);
+								struct ast_format_cap *native = iaxs[fr->callno]->owner->nativeformats;
+								if (orignative) {
+									ast_format_cap_set(native, &f.subclass.format);
+									if (iaxs[fr->callno]->owner->readformat.id) {
+										ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
+									}
+									ast_format_cap_copy(native, orignative);
+									ast_channel_unlock(iaxs[fr->callno]->owner);
+									orignative = ast_format_cap_destroy(orignative);
+								}
 							}
 						} else {
 							ast_debug(1, "Neat, somebody took away the channel at a magical time but i found it!\n");
@@ -10281,9 +10394,9 @@ static int socket_process(struct iax2_thread *thread)
 			}
 		}
 		if (f.frametype == AST_FRAME_VIDEO) {
-			if (f.subclass.codec != iaxs[fr->callno]->videoformat) {
-				ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(f.subclass.codec & ~0x1LL));
-				iaxs[fr->callno]->videoformat = f.subclass.codec & ~0x1LL;
+			if (f.subclass.format.id != ast_format_id_from_old_bitfield(iaxs[fr->callno]->videoformat)) {
+				ast_debug(1, "Ooh, video format changed to %s\n", ast_getformatname(&f.subclass.format));
+				iaxs[fr->callno]->videoformat = ast_format_to_old_bitfield(&f.subclass.format);
 			}
 		}
 		if (f.frametype == AST_FRAME_CONTROL && iaxs[fr->callno]->owner) {
@@ -10471,11 +10584,12 @@ static int socket_process(struct iax2_thread *thread)
 							strcpy(caller_pref_buf, "disabled");
 							strcpy(host_pref_buf, "disabled");
 						} else {
+							struct ast_format tmpfmt;
 							using_prefs = "mine";
 							/* If the information elements are in here... use them */
 							if (ies.codec_prefs)
 								ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
-							if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+							if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 								/* If we are codec_first_choice we let the caller have the 1st shot at picking the codec.*/
 								if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
 									pref = iaxs[fr->callno]->rprefs;
@@ -10486,7 +10600,7 @@ static int socket_process(struct iax2_thread *thread)
 							} else
 								pref = iaxs[fr->callno]->prefs;
 
-							format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
+							format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
 							ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
 							ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
 						}
@@ -10506,14 +10620,14 @@ static int socket_process(struct iax2_thread *thread)
 									if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
 										ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
 											ast_inet_ntoa(sin.sin_addr),
-											ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
-											ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+											iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
+											iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
 									} else {
 										ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
 											ast_inet_ntoa(sin.sin_addr),
-											ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
-											ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
-											ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+											iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
+											iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
+											iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
 									}
 								}
 							} else {
@@ -10525,12 +10639,13 @@ static int socket_process(struct iax2_thread *thread)
 									if(ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOPREFS)) {
 										using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
 										memset(&pref, 0, sizeof(pref));
-										format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+										format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
 										strcpy(caller_pref_buf,"disabled");
 										strcpy(host_pref_buf,"disabled");
 									} else {
+										struct ast_format tmpfmt;
 										using_prefs = "mine";
-										if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+										if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 											/* Do the opposite of what we tried above. */
 											if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
 												pref = iaxs[fr->callno]->prefs;
@@ -10538,9 +10653,9 @@ static int socket_process(struct iax2_thread *thread)
 												pref = iaxs[fr->callno]->rprefs;
 												using_prefs = "caller";
 											}
-											format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
+											format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
 										} else /* if no codec_prefs IE do it the old way */
-											format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+											format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
 									}
 								}
 
@@ -10549,7 +10664,7 @@ static int socket_process(struct iax2_thread *thread)
 									memset(&ied0, 0, sizeof(ied0));
 									iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
 									iax_ie_append_byte(&ied0, IAX_IE_CAUSECODE, AST_CAUSE_BEARERCAPABILITY_NOTAVAIL);
-									ast_log(LOG_ERROR, "No best format in '%s'???\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
+									ast_log(LOG_ERROR, "No best format in '%s'???\n", iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
 									send_command_final(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied0.buf, ied0.pos, -1);
 									if (!iaxs[fr->callno]) {
 										break;
@@ -10557,9 +10672,9 @@ static int socket_process(struct iax2_thread *thread)
 									if (authdebug) {
 										ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
 											ast_inet_ntoa(sin.sin_addr),
-											ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
-											ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
-											ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+											iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat),
+											iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
+											iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
 									}
 									ast_set_flag64(iaxs[fr->callno], IAX_ALREADYGONE);
 									break;
@@ -10582,11 +10697,11 @@ static int socket_process(struct iax2_thread *thread)
 												"%spriority = %s\n",
 												ast_inet_ntoa(sin.sin_addr), 
 												VERBOSE_PREFIX_4,
-												ast_getformatname(iaxs[fr->callno]->peerformat), 
+												iax2_getformatname(iaxs[fr->callno]->peerformat), 
 												VERBOSE_PREFIX_4,
 												caller_pref_buf,
 												VERBOSE_PREFIX_4,
-												ast_getformatname(format), 
+												iax2_getformatname(format), 
 												VERBOSE_PREFIX_4,
 												host_pref_buf, 
 												VERBOSE_PREFIX_4,
@@ -10730,11 +10845,11 @@ static int socket_process(struct iax2_thread *thread)
 					iaxs[fr->callno]->peerformat = ies.format;
 				} else {
 					if (iaxs[fr->callno]->owner)
-						iaxs[fr->callno]->peerformat = iaxs[fr->callno]->owner->nativeformats;
+						iaxs[fr->callno]->peerformat = ast_format_cap_to_old_bitfield(iaxs[fr->callno]->owner->nativeformats);
 					else
 						iaxs[fr->callno]->peerformat = iaxs[fr->callno]->capability;
 				}
-				ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), ast_getformatname(iaxs[fr->callno]->peerformat));
+				ast_verb(3, "Call accepted by %s (format %s)\n", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr), iax2_getformatname(iaxs[fr->callno]->peerformat));
 				if (!(iaxs[fr->callno]->peerformat & iaxs[fr->callno]->capability)) {
 					memset(&ied0, 0, sizeof(ied0));
 					iax_ie_append_str(&ied0, IAX_IE_CAUSE, "Unable to negotiate codec");
@@ -10747,22 +10862,23 @@ static int socket_process(struct iax2_thread *thread)
 						char tmp1[256], tmp2[256];
 						ast_log(LOG_NOTICE, "Rejected call to %s, format %s incompatible with our capability %s.\n",
 							ast_inet_ntoa(sin.sin_addr),
-							ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
-							ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+							iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+							iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
 					}
 				} else {
 					ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 					iax2_lock_owner(fr->callno);
 					if (iaxs[fr->callno] && iaxs[fr->callno]->owner) {
+						char tmp[256];
 						/* Switch us to use a compatible format */
-						iaxs[fr->callno]->owner->nativeformats = iaxs[fr->callno]->peerformat;
-						ast_verb(3, "Format for call is %s\n", ast_getformatname(iaxs[fr->callno]->owner->nativeformats));
+						ast_format_cap_from_old_bitfield(iaxs[fr->callno]->owner->nativeformats, iaxs[fr->callno]->peerformat);
+						ast_verb(3, "Format for call is %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->owner->nativeformats));
 
 						/* Setup read/write formats properly. */
-						if (iaxs[fr->callno]->owner->writeformat)
-							ast_set_write_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->writeformat);	
-						if (iaxs[fr->callno]->owner->readformat)
-							ast_set_read_format(iaxs[fr->callno]->owner, iaxs[fr->callno]->owner->readformat);	
+						if (iaxs[fr->callno]->owner->writeformat.id)
+							ast_set_write_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->writeformat);
+						if (iaxs[fr->callno]->owner->readformat.id)
+							ast_set_read_format(iaxs[fr->callno]->owner, &iaxs[fr->callno]->owner->readformat);
 						ast_channel_unlock(iaxs[fr->callno]->owner);
 					}
 				}
@@ -10921,10 +11037,11 @@ static int socket_process(struct iax2_thread *thread)
 						strcpy(caller_pref_buf, "disabled");
 						strcpy(host_pref_buf, "disabled");
 					} else {
+						struct ast_format tmpfmt;
 						using_prefs = "mine";
 						if (ies.codec_prefs)
 							ast_codec_pref_convert(&iaxs[fr->callno]->rprefs, ies.codec_prefs, 32, 0);
-						if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+						if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 							if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
 								pref = iaxs[fr->callno]->rprefs;
 								using_prefs = "caller";
@@ -10933,7 +11050,7 @@ static int socket_process(struct iax2_thread *thread)
 							}
 						} else /* if no codec_prefs IE do it the old way */
 							pref = iaxs[fr->callno]->prefs;
-						format = ast_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
+						format = iax2_codec_choose(&pref, iaxs[fr->callno]->capability & iaxs[fr->callno]->peercapability, 0);
 						ast_codec_pref_string(&iaxs[fr->callno]->rprefs, caller_pref_buf, sizeof(caller_pref_buf) - 1);
 						ast_codec_pref_string(&iaxs[fr->callno]->prefs, host_pref_buf, sizeof(host_pref_buf) - 1);
 					}
@@ -10941,22 +11058,22 @@ static int socket_process(struct iax2_thread *thread)
 						char tmp1[256], tmp2[256], tmp3[256];
 						if(!ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
 							ast_debug(1, "We don't do requested format %s, falling back to peer capability '%s'\n",
-								ast_getformatname(iaxs[fr->callno]->peerformat),
-								ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
+								iax2_getformatname(iaxs[fr->callno]->peerformat),
+								iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability));
 							format = iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability;
 						}
 						if (!format) {
 							if (authdebug) {
 								if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
 									ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n", ast_inet_ntoa(sin.sin_addr),
-										ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
-										ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+										iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+										iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
 								} else {
 									ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
 										ast_inet_ntoa(sin.sin_addr),
-										ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
-										ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
-										ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+										iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+										iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
+										iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
 								}
 							}
 							memset(&ied0, 0, sizeof(ied0));
@@ -10976,12 +11093,13 @@ static int socket_process(struct iax2_thread *thread)
 									using_prefs = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ? "reqonly" : "disabled";
 									memset(&pref, 0, sizeof(pref));
 									format = ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP) ?
-										iaxs[fr->callno]->peerformat : ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
+										iaxs[fr->callno]->peerformat : iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);
 									strcpy(caller_pref_buf,"disabled");
 									strcpy(host_pref_buf,"disabled");
 								} else {
+									struct ast_format tmpfmt;
 									using_prefs = "mine";
-									if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0)) {
+									if (ast_codec_pref_index(&iaxs[fr->callno]->rprefs, 0, &tmpfmt)) {
 										/* Do the opposite of what we tried above. */
 										if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_USER_FIRST)) {
 											pref = iaxs[fr->callno]->prefs;
@@ -10989,27 +11107,27 @@ static int socket_process(struct iax2_thread *thread)
 											pref = iaxs[fr->callno]->rprefs;
 											using_prefs = "caller";
 										}
-										format = ast_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
+										format = iax2_codec_choose(&pref, iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability, 1);
 									} else /* if no codec_prefs IE do it the old way */
-										format = ast_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);	
+										format = iax2_best_codec(iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability);	
 								}
 							}
 							if (!format) {
 								char tmp1[256], tmp2[256], tmp3[256];
 								ast_log(LOG_ERROR, "No best format in %s???\n",
-									ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
+									iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peercapability & iaxs[fr->callno]->capability));
 								if (authdebug) {
 									if (ast_test_flag64(iaxs[fr->callno], IAX_CODEC_NOCAP)) {
 										ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested '%s' incompatible with our capability '%s'.\n",
 											ast_inet_ntoa(sin.sin_addr),
-											ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
-											ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
+											iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+											iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->capability));
 									} else {
 										ast_log(LOG_NOTICE, "Rejected connect attempt from %s, requested/capability '%s'/'%s' incompatible with our capability '%s'.\n",
 											ast_inet_ntoa(sin.sin_addr),
-											ast_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
-											ast_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
-											ast_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
+											iax2_getformatname_multiple(tmp1, sizeof(tmp1), iaxs[fr->callno]->peerformat),
+											iax2_getformatname_multiple(tmp2, sizeof(tmp2), iaxs[fr->callno]->peercapability),
+											iax2_getformatname_multiple(tmp3, sizeof(tmp3), iaxs[fr->callno]->capability));
 									}
 								}
 								memset(&ied0, 0, sizeof(ied0));
@@ -11038,11 +11156,11 @@ static int socket_process(struct iax2_thread *thread)
 											"%spriority = %s\n", 
 											ast_inet_ntoa(sin.sin_addr), 
 											VERBOSE_PREFIX_4,
-											ast_getformatname(iaxs[fr->callno]->peerformat),
+											iax2_getformatname(iaxs[fr->callno]->peerformat),
 											VERBOSE_PREFIX_4,
 											caller_pref_buf,
 											VERBOSE_PREFIX_4,
-											ast_getformatname(format),
+											iax2_getformatname(format),
 											VERBOSE_PREFIX_4,
 											host_pref_buf,
 											VERBOSE_PREFIX_4,
@@ -11117,7 +11235,7 @@ immediatedial:
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						ast_verb(3, "Accepting DIAL from %s, formats = %s\n",
 							ast_inet_ntoa(sin.sin_addr),
-							ast_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
+							iax2_getformatname_multiple(tmp, sizeof(tmp), iaxs[fr->callno]->peerformat));
 						ast_set_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED);
 						send_command(iaxs[fr->callno], AST_FRAME_CONTROL, AST_CONTROL_PROGRESS, 0, NULL, 0, -1);
 						if (!(c = ast_iax2_new(fr->callno, AST_STATE_RING, iaxs[fr->callno]->peerformat, NULL)))
@@ -11396,9 +11514,12 @@ immediatedial:
 			send_command_immediate(iaxs[fr->callno], AST_FRAME_IAX, IAX_COMMAND_ACK, fr->ts, NULL, 0,fr->iseqno);
 	} else if (minivid) {
 		f.frametype = AST_FRAME_VIDEO;
-		if (iaxs[fr->callno]->videoformat > 0) 
-			f.subclass.codec = iaxs[fr->callno]->videoformat | (ntohs(vh->ts) & 0x8000LL ? 1 : 0);
-		else {
+		if (iaxs[fr->callno]->videoformat > 0) {
+			if (ntohs(vh->ts) & 0x8000LL) {
+				ast_format_set_video_mark(&f.subclass.format);
+			}
+			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->videoformat);
+		} else {
 			ast_log(LOG_WARNING, "Received mini frame before first full video frame\n");
 			iax2_vnak(fr->callno);
 			ast_variables_destroy(ies.vars);
@@ -11420,7 +11541,7 @@ immediatedial:
 		/* A mini frame */
 		f.frametype = AST_FRAME_VOICE;
 		if (iaxs[fr->callno]->voiceformat > 0)
-			f.subclass.codec = iaxs[fr->callno]->voiceformat;
+			ast_format_from_old_bitfield(&f.subclass.format, iaxs[fr->callno]->voiceformat);
 		else {
 			ast_debug(1, "Received mini frame before first full voice frame\n");
 			iax2_vnak(fr->callno);
@@ -11492,7 +11613,7 @@ immediatedial:
 	if (f.datalen && (f.frametype == AST_FRAME_VOICE)) {
 		f.samples = ast_codec_get_samples(&f);
 		/* We need to byteswap incoming slinear samples from network byte order */
-		if (f.subclass.codec == AST_FORMAT_SLINEAR)
+		if (f.subclass.format.id == AST_FORMAT_SLINEAR)
 			ast_frame_byteswap_be(&f);
 	} else
 		f.samples = 0;
@@ -11982,11 +12103,10 @@ static void free_context(struct iax2_context *con)
 	}
 }
 
-static struct ast_channel *iax2_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *iax2_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	int callno;
 	int res;
-	format_t fmt, native;
 	struct sockaddr_in sin;
 	struct ast_channel *c;
 	struct parsed_dial_string pds;
@@ -12001,12 +12121,11 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
 		ast_log(LOG_WARNING, "No peer provided in the IAX2 dial string '%s'\n", (char *) data);
 		return NULL;
 	}
-	       
 	memset(&cai, 0, sizeof(cai));
 	cai.capability = iax2_capability;
 
 	ast_copy_flags64(&cai, &globalflags, IAX_NOTRANSFER | IAX_TRANSFERMEDIA | IAX_USEJITTERBUF | IAX_FORCEJITTERBUF | IAX_SENDCONNECTEDLINE | IAX_RECVCONNECTEDLINE);
-	
+
 	/* Populate our address from the given */
 	if (create_addr(pds.peer, NULL, &sin, &cai)) {
 		*cause = AST_CAUSE_UNREGISTERED;
@@ -12039,23 +12158,28 @@ static struct ast_channel *iax2_request(const char *type, format_t format, const
 	ast_mutex_unlock(&iaxsl[callno]);
 
 	if (c) {
+		struct ast_format_cap *joint;
+
 		/* Choose a format we can live with */
-		if (c->nativeformats & format) 
-			c->nativeformats &= format;
-		else {
-			native = c->nativeformats;
-			fmt = format;
-			res = ast_translator_best_choice(&fmt, &native);
+		if ((joint = ast_format_cap_joint(c->nativeformats, cap))) {
+			ast_format_cap_copy(c->nativeformats, joint);
+			joint = ast_format_cap_destroy(joint);
+		} else {
+			struct ast_format best_fmt_cap;
+			struct ast_format best_fmt_native;
+			res = ast_translator_best_choice(cap, c->nativeformats, &best_fmt_cap, &best_fmt_native);
 			if (res < 0) {
+				char tmp[256];
+				char tmp2[256];
 				ast_log(LOG_WARNING, "Unable to create translator path for %s to %s on %s\n",
-					ast_getformatname(c->nativeformats), ast_getformatname(fmt), c->name);
+					ast_getformatname_multiple(tmp, sizeof(tmp), c->nativeformats), ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), c->name);
 				ast_hangup(c);
 				return NULL;
 			}
-			c->nativeformats = native;
+			ast_format_cap_set(c->nativeformats, &best_fmt_native);
 		}
-		c->readformat = ast_best_codec(c->nativeformats);
-		c->writeformat = c->readformat;
+		ast_best_codec(c->nativeformats, &c->readformat);
+		ast_format_copy(&c->writeformat, &c->readformat);
 	}
 
 	return c;
@@ -12429,9 +12553,9 @@ static struct iax2_peer *build_peer(const char *name, struct ast_variable *v, st
 			} else if (!strcasecmp(v->name, "username")) {
 				ast_string_field_set(peer, username, v->value);
 			} else if (!strcasecmp(v->name, "allow")) {
-				ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
+				iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 1);
 			} else if (!strcasecmp(v->name, "disallow")) {
-				ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
+				iax2_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, 0);
 			} else if (!strcasecmp(v->name, "callerid")) {
 				if (!ast_strlen_zero(v->value)) {
 					char name2[80];
@@ -12641,9 +12765,9 @@ static struct iax2_user *build_user(const char *name, struct ast_variable *v, st
 					}
 				}
 			} else if (!strcasecmp(v->name, "allow")) {
-				ast_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
+				iax2_parse_allow_disallow(&user->prefs, &user->capability, v->value, 1);
 			} else if (!strcasecmp(v->name, "disallow")) {
-				ast_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
+				iax2_parse_allow_disallow(&user->prefs, &user->capability,v->value, 0);
 			} else if (!strcasecmp(v->name, "trunk")) {
 				ast_set2_flag64(user, ast_true(v->value), IAX_TRUNK);	
 				if (ast_test_flag64(user, IAX_TRUNK) && !timer) {
@@ -12903,7 +13027,7 @@ static void set_config_destroy(void)
 static int set_config(const char *config_file, int reload)
 {
 	struct ast_config *cfg, *ucfg;
-	format_t capability = iax2_capability;
+	iax2_format capability = iax2_capability;
 	struct ast_variable *v;
 	char *cat;
 	const char *utype;
@@ -13164,9 +13288,9 @@ static int set_config(const char *config_file, int reload)
 			} else
 				ast_log(LOG_WARNING, "bandwidth must be either low, medium, or high\n");
 		} else if (!strcasecmp(v->name, "allow")) {
-			ast_parse_allow_disallow(&prefs, &capability, v->value, 1);
+			iax2_parse_allow_disallow(&prefs, &capability, v->value, 1);
 		} else if (!strcasecmp(v->name, "disallow")) {
-			ast_parse_allow_disallow(&prefs, &capability, v->value, 0);
+			iax2_parse_allow_disallow(&prefs, &capability, v->value, 0);
 		} else if (!strcasecmp(v->name, "register")) {
 			iax2_register(v->value, v->lineno);
 		} else if (!strcasecmp(v->name, "iaxcompat")) {
@@ -13802,19 +13926,18 @@ static int function_iaxpeer(struct ast_channel *chan, const char *cmd, char *dat
 	} else  if (!strcasecmp(colname, "callerid_num")) {
 		ast_copy_string(buf, peer->cid_num, len);
 	} else  if (!strcasecmp(colname, "codecs")) {
-		ast_getformatname_multiple(buf, len -1, peer->capability);
+		iax2_getformatname_multiple(buf, len -1, peer->capability);
 	} else  if (!strncasecmp(colname, "codec[", 6)) {
 		char *codecnum, *ptr;
-		int codec = 0;
-		
+		struct ast_format tmpfmt;
 		codecnum = strchr(colname, '[');
 		*codecnum = '\0';
 		codecnum++;
 		if ((ptr = strchr(codecnum, ']'))) {
 			*ptr = '\0';
 		}
-		if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
-			ast_copy_string(buf, ast_getformatname(codec), len);
+		if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &tmpfmt))) {
+			ast_copy_string(buf, ast_getformatname(&tmpfmt), len);
 		} else {
 			buf[0] = '\0';
 		}
@@ -14273,6 +14396,8 @@ static int __unload_module(void)
 	if (con)
 		ast_context_destroy(con, "IAX2");
 	ast_unload_realtime("iaxpeers");
+
+	iax2_tech.capabilities = ast_format_cap_destroy(iax2_tech.capabilities);
 	return 0;
 }
 
@@ -14436,7 +14561,7 @@ static int peers_data_provider_get(const struct ast_data_search *search,
 
 		ast_data_add_structure(iax2_peer, data_peer, peer);
 
-		ast_data_add_codecs(data_peer, "codecs", peer->capability);
+		iax2_data_add_codecs(data_peer, "codecs", peer->capability);
 
 		peer_status(peer, status, sizeof(status));
 		ast_data_add_str(data_peer, "status", status);
@@ -14500,7 +14625,7 @@ static int users_data_provider_get(const struct ast_data_search *search,
 
 		ast_data_add_structure(iax2_user, data_user, user);
 
-		ast_data_add_codecs(data_user, "codecs", user->capability);
+		iax2_data_add_codecs(data_user, "codecs", user->capability);
 
 		if (!ast_strlen_zero(user->secret)) {
 			ast_copy_string(auth, user->secret, sizeof(auth));
@@ -14576,6 +14701,11 @@ static int load_module(void)
 	int x = 0;
 	struct iax2_registry *reg = NULL;
 
+	if (!(iax2_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add_all(iax2_tech.capabilities);
+
 	if (load_objects()) {
 		return AST_MODULE_LOAD_FAILURE;
 	}
diff --git a/channels/chan_jingle.c b/channels/chan_jingle.c
index fd84f1f27b914872f7b4c4ecffbd9182208c45e4..93d81d954bd63337ec76eb4961a86f43057ab98d 100644
--- a/channels/chan_jingle.c
+++ b/channels/chan_jingle.c
@@ -104,7 +104,6 @@ struct jingle_pvt {
 	iksrule *ringrule;               /*!< Rule for matching RING request */
 	int initiator;                   /*!< If we're the initiator */
 	int alreadygone;
-	format_t capability;
 	struct ast_codec_pref prefs;
 	struct jingle_candidate *theircandidates;
 	struct jingle_candidate *ourcandidates;
@@ -116,8 +115,9 @@ struct jingle_pvt {
 	struct ast_rtp_instance *rtp;             /*!< RTP audio session */
 	char video_content_name[100];    /*!< name attribute of content tag */
 	struct ast_rtp_instance *vrtp;            /*!< RTP video session */
-	format_t jointcapability;             /*!< Supported capability at both ends (codecs ) */
-	format_t peercapability;
+	struct ast_format_cap *cap;
+	struct ast_format_cap *jointcap;             /*!< Supported capability at both ends (codecs ) */
+	struct ast_format_cap *peercap;
 	struct jingle_pvt *next;	/* Next entity */
 };
 
@@ -147,7 +147,7 @@ struct jingle {
 	char user[100];
 	char context[100];
 	char accountcode[AST_MAX_ACCOUNT_CODE];	/*!< Account code */
-	format_t capability;
+	struct ast_format_cap *cap;
 	ast_group_t callgroup;	/*!< Call group */
 	ast_group_t pickupgroup;	/*!< Pickup group */
 	int callingpres;		/*!< Calling presentation */
@@ -164,12 +164,12 @@ struct jingle_container {
 static const char desc[] = "Jingle Channel";
 static const char channel_type[] = "Jingle";
 
-static format_t global_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263;
+static struct ast_format_cap *global_capability;
 
 AST_MUTEX_DEFINE_STATIC(jinglelock); /*!< Protect the interface list (of jingle_pvt's) */
 
 /* Forward declarations */
-static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int jingle_sendtext(struct ast_channel *ast, const char *text);
 static int jingle_digit_begin(struct ast_channel *ast, char digit);
 static int jingle_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
@@ -187,10 +187,9 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
 static char *jingle_do_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 
 /*! \brief PBX interface structure for channel registration */
-static const struct ast_channel_tech jingle_tech = {
+static struct ast_channel_tech jingle_tech = {
 	.type = "Jingle",
 	.description = "Jingle Channel Driver",
-	.capabilities = AST_FORMAT_AUDIO_MASK,
 	.requester = jingle_request,
 	.send_text = jingle_sendtext,
 	.send_digit_begin = jingle_digit_begin,
@@ -226,6 +225,7 @@ static struct jingle_container jingle_list;
 
 static void jingle_member_destroy(struct jingle *obj)
 {
+	obj->cap = ast_format_cap_destroy(obj->cap);
 	ast_free(obj);
 }
 
@@ -255,7 +255,7 @@ static struct jingle *find_jingle(char *name, char *connection)
 }
 
 
-static void add_codec_to_answer(const struct jingle_pvt *p, int codec, iks *dcodecs)
+static void add_codec_to_answer(const struct jingle_pvt *p, struct ast_format *codec, iks *dcodecs)
 {
 	char *format = ast_getformatname(codec);
 
@@ -301,10 +301,10 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
 	struct aji_client *c = client->connection;
 	iks *iq, *jingle, *dcodecs, *payload_red, *payload_audio, *payload_cn;
 	int x;
-	format_t pref_codec = 0;
-	int alreadysent = 0;
+	struct ast_format pref_codec;
+	struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
 
-	if (p->initiator)
+	if (p->initiator || !alreadysent)
 		return 1;
 
 	iq = iks_new("iq");
@@ -313,15 +313,15 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
 	if (iq && jingle && dcodecs) {
 		iks_insert_attrib(dcodecs, "xmlns", JINGLE_AUDIO_RTP_NS);
 
-		for (x = 0; x < 64; x++) {
-			if (!(pref_codec = ast_codec_pref_index(&client->prefs, x)))
+		for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+			if (!(ast_codec_pref_index(&client->prefs, x, &pref_codec)))
 				break;
-			if (!(client->capability & pref_codec))
+			if (!(ast_format_cap_iscompatible(client->cap, &pref_codec)))
 				continue;
-			if (alreadysent & pref_codec)
+			if ((ast_format_cap_iscompatible(alreadysent, &pref_codec)))
 				continue;
-			add_codec_to_answer(p, pref_codec, dcodecs);
-			alreadysent |= pref_codec;
+			add_codec_to_answer(p, &pref_codec, dcodecs);
+			ast_format_cap_add(alreadysent, &pref_codec);
 		}
 		payload_red = iks_new("payload-type");
 		iks_insert_attrib(payload_red, "id", "117");
@@ -358,6 +358,7 @@ static int jingle_accept_call(struct jingle *client, struct jingle_pvt *p)
 		iks_delete(jingle);
 		iks_delete(iq);
 	}
+	alreadysent = ast_format_cap_destroy(alreadysent);
 	return 1;
 }
 
@@ -405,13 +406,15 @@ static enum ast_rtp_glue_result jingle_get_rtp_peer(struct ast_channel *chan, st
 	return res;
 }
 
-static format_t jingle_get_codec(struct ast_channel *chan)
+static void jingle_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
 	struct jingle_pvt *p = chan->tech_pvt;
-	return p->peercapability;
+	ast_mutex_lock(&p->lock);
+	ast_format_cap_copy(result, p->peercap);
+	ast_mutex_unlock(&p->lock);
 }
 
-static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, format_t codecs, int nat_active)
+static int jingle_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *tpeer, const struct ast_format_cap *cap, int nat_active)
 {
 	struct jingle_pvt *p;
 
@@ -772,6 +775,16 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
 		return NULL;
 	}
 
+	tmp->cap = ast_format_cap_alloc_nolock();
+	tmp->jointcap = ast_format_cap_alloc_nolock();
+	tmp->peercap = ast_format_cap_alloc_nolock();
+	if (!tmp->cap || !tmp->jointcap || !tmp->peercap) {
+		tmp->cap = ast_format_cap_destroy(tmp->cap);
+		tmp->jointcap = ast_format_cap_destroy(tmp->jointcap);
+		tmp->peercap = ast_format_cap_destroy(tmp->peercap);
+		ast_free(tmp);
+		return NULL;
+	}
 	memcpy(&tmp->prefs, &client->prefs, sizeof(tmp->prefs));
 
 	if (sid) {
@@ -803,8 +816,8 @@ static struct jingle_pvt *jingle_alloc(struct jingle *client, const char *from,
 static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *i, int state, const char *title, const char *linkedid)
 {
 	struct ast_channel *tmp;
-	int fmt;
-	int what;
+	struct ast_format_cap *what;  /* SHALLOW COPY DO NOT DESTROY */
+	struct ast_format tmpfmt;
 	const char *str;
 
 	if (title)
@@ -820,10 +833,10 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
 
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
-	if (i->jointcapability)
-		what = i->jointcapability;
-	else if (i->capability)
-		what = i->capability;
+	if (!ast_format_cap_is_empty(i->jointcap))
+		what = i->jointcap;
+	else if (!(ast_format_cap_is_empty(i->cap)))
+		what = i->cap;
 	else
 		what = global_capability;
 
@@ -831,8 +844,16 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
 	if (i->rtp)
 		ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(i->rtp), i->rtp, &i->prefs);
 
-	tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | (i->jointcapability & AST_FORMAT_VIDEO_MASK);
-	fmt = ast_best_codec(tmp->nativeformats);
+	ast_codec_choose(&i->prefs, what, 1, &tmpfmt);
+	ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+
+	ast_format_cap_iter_start(i->jointcap);
+	while (!(ast_format_cap_iter_next(i->jointcap, &tmpfmt))) {
+		if (AST_FORMAT_GET_TYPE(tmpfmt.id) == AST_FORMAT_TYPE_VIDEO) {
+			ast_format_cap_add(tmp->nativeformats, &tmpfmt);
+		}
+	}
+	ast_format_cap_iter_end(i->jointcap);
 
 	if (i->rtp) {
 		ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(i->rtp, 0));
@@ -845,10 +866,13 @@ static struct ast_channel *jingle_new(struct jingle *client, struct jingle_pvt *
 	if (state == AST_STATE_RING)
 		tmp->rings = 1;
 	tmp->adsicpe = AST_ADSI_UNAVAILABLE;
-	tmp->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	tmp->readformat = fmt;
-	tmp->rawreadformat = fmt;
+
+
+	ast_best_codec(tmp->nativeformats, &tmpfmt);
+	ast_format_copy(&tmp->writeformat, &tmpfmt);
+	ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+	ast_format_copy(&tmp->readformat, &tmpfmt);
+	ast_format_copy(&tmp->rawreadformat, &tmpfmt);
 	tmp->tech_pvt = i;
 
 	tmp->callgroup = client->callgroup;
@@ -955,6 +979,10 @@ static void jingle_free_pvt(struct jingle *client, struct jingle_pvt *p)
 	if (p->vrtp)
 		ast_rtp_instance_destroy(p->vrtp);
 	jingle_free_candidates(p->theircandidates);
+	p->cap = ast_format_cap_destroy(p->cap);
+	p->jointcap = ast_format_cap_destroy(p->jointcap);
+	p->peercap = ast_format_cap_destroy(p->peercap);
+
 	ast_free(p);
 }
 
@@ -1185,12 +1213,12 @@ static struct ast_frame *jingle_rtp_read(struct ast_channel *ast, struct jingle_
 	if (p->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
-				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
-				p->owner->nativeformats =
-					(p->owner->nativeformats & AST_FORMAT_VIDEO_MASK) | f->subclass.codec;
-				ast_set_read_format(p->owner, p->owner->readformat);
-				ast_set_write_format(p->owner, p->owner->writeformat);
+			if (!(ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format))) {
+				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
+				ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
+				ast_set_read_format(p->owner, &p->owner->readformat);
+				ast_set_write_format(p->owner, &p->owner->writeformat);
 			}
 /*			if ((ast_test_flag(p, SIP_DTMF) == SIP_DTMF_INBAND) && p->vad) {
 				f = ast_dsp_process(p->owner, p->vad, f);
@@ -1222,13 +1250,13 @@ static int jingle_write(struct ast_channel *ast, struct ast_frame *frame)
 
 	switch (frame->frametype) {
 	case AST_FRAME_VOICE:
-		if (!(frame->subclass.codec & ast->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
 			ast_log(LOG_WARNING,
 					"Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
-					ast_getformatname(frame->subclass.codec),
+					ast_getformatname(&frame->subclass.format),
 					ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
-					ast_getformatname(ast->readformat),
-					ast_getformatname(ast->writeformat));
+					ast_getformatname(&ast->readformat),
+					ast_getformatname(&ast->writeformat));
 			return 0;
 		}
 		if (p) {
@@ -1464,7 +1492,7 @@ static int jingle_call(struct ast_channel *ast, char *dest, int timeout)
 	}
 
 	ast_setstate(ast, AST_STATE_RING);
-	p->jointcapability = p->capability;
+	ast_format_cap_copy(p->jointcap, p->cap);
 	if (!p->ringrule) {
 		ast_copy_string(p->ring, p->parent->connection->mid, sizeof(p->ring));
 		p->ringrule = iks_filter_add_rule(p->parent->connection->f, jingle_ringing_ack, p,
@@ -1498,7 +1526,7 @@ static int jingle_hangup(struct ast_channel *ast)
 }
 
 /*! \brief Part of PBX interface */
-static struct ast_channel *jingle_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *jingle_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct jingle_pvt *p = NULL;
 	struct jingle *client = NULL;
@@ -1588,8 +1616,8 @@ static char *jingle_show_channels(struct ast_cli_entry *e, int cmd, struct ast_c
 					chan->name,
 					jid,
 					resource,
-					ast_getformatname(chan->readformat),
-					ast_getformatname(chan->writeformat)					
+					ast_getformatname(&chan->readformat),
+					ast_getformatname(&chan->writeformat)
 					);
 			else 
 				ast_log(LOG_WARNING, "No available channel\n");
@@ -1717,9 +1745,9 @@ static int jingle_create_member(char *label, struct ast_variable *var, int allow
 		if (!strcasecmp(var->name, "username"))
 			ast_copy_string(member->user, var->value, sizeof(member->user));
 		else if (!strcasecmp(var->name, "disallow"))
-			ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 0);
+			ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 0);
 		else if (!strcasecmp(var->name, "allow"))
-			ast_parse_allow_disallow(&member->prefs, &member->capability, var->value, 1);
+			ast_parse_allow_disallow(&member->prefs, member->cap, var->value, 1);
 		else if (!strcasecmp(var->name, "context"))
 			ast_copy_string(member->context, var->value, sizeof(member->context));
 #if 0
@@ -1787,9 +1815,9 @@ static int jingle_load_config(void)
 			allowguest =
 				(ast_true(ast_variable_retrieve(cfg, "general", "allowguest"))) ? 1 : 0;
 		else if (!strcasecmp(var->name, "disallow"))
-			ast_parse_allow_disallow(&prefs, &global_capability, var->value, 0);
+			ast_parse_allow_disallow(&prefs, global_capability, var->value, 0);
 		else if (!strcasecmp(var->name, "allow"))
-			ast_parse_allow_disallow(&prefs, &global_capability, var->value, 1);
+			ast_parse_allow_disallow(&prefs, global_capability, var->value, 1);
 		else if (!strcasecmp(var->name, "context"))
 			ast_copy_string(context, var->value, sizeof(context));
 		else if (!strcasecmp(var->name, "externip"))
@@ -1818,6 +1846,7 @@ static int jingle_load_config(void)
 			member = ast_calloc(1, sizeof(*member));
 			ASTOBJ_INIT(member);
 			ASTOBJ_WRLOCK(member);
+			member->cap = ast_format_cap_alloc_nolock();
 			if (!strcasecmp(cat, "guest")) {
 				ast_copy_string(member->name, "guest", sizeof(member->name));
 				ast_copy_string(member->user, "guest", sizeof(member->user));
@@ -1826,10 +1855,10 @@ static int jingle_load_config(void)
 				member->prefs = prefs;
 				while (var) {
 					if (!strcasecmp(var->name, "disallow"))
-						ast_parse_allow_disallow(&member->prefs, &member->capability,
+						ast_parse_allow_disallow(&member->prefs, member->cap,
 												 var->value, 0);
 					else if (!strcasecmp(var->name, "allow"))
-						ast_parse_allow_disallow(&member->prefs, &member->capability,
+						ast_parse_allow_disallow(&member->prefs, member->cap,
 												 var->value, 1);
 					else if (!strcasecmp(var->name, "context"))
 						ast_copy_string(member->context, var->value,
@@ -1884,8 +1913,23 @@ static int load_module(void)
 {
 	struct ast_sockaddr ourip_tmp;
 	struct ast_sockaddr bindaddr_tmp;
+	struct ast_format tmpfmt;
 
 	char *jabber_loaded = ast_module_helper("", "res_jabber.so", 0, 0, 0, 0);
+
+	if (!(jingle_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_format_cap_add_all_by_type(jingle_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+	if (!(global_capability = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_H263, 0));
+
 	free(jabber_loaded);
 	if (!jabber_loaded) {
 		/* Dependency module has a different name, if embedded */
@@ -1965,6 +2009,8 @@ static int unload_module(void)
 	}
 	ASTOBJ_CONTAINER_DESTROYALL(&jingle_list, jingle_member_destroy);
 	ASTOBJ_CONTAINER_DESTROY(&jingle_list);
+
+	global_capability = ast_format_cap_destroy(global_capability);
 	return 0;
 }
 
diff --git a/channels/chan_local.c b/channels/chan_local.c
index e80722c239e7a20c94b9ea7d3f107e56b2764bb1..fbe1e530e04a06260021ea31136923829d189191 100644
--- a/channels/chan_local.c
+++ b/channels/chan_local.c
@@ -88,7 +88,7 @@ static struct ast_jb_conf g_jb_conf = {
 	.target_extra = -1,
 };
 
-static struct ast_channel *local_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int local_digit_begin(struct ast_channel *ast, char digit);
 static int local_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int local_call(struct ast_channel *ast, char *dest, int timeout);
@@ -106,10 +106,9 @@ static int local_queryoption(struct ast_channel *ast, int option, void *data, in
 static int local_setoption(struct ast_channel *chan, int option, void *data, int datalen);
 
 /* PBX interface structure for channel registration */
-static const struct ast_channel_tech local_tech = {
+static struct ast_channel_tech local_tech = {
 	.type = "Local",
 	.description = tdesc,
-	.capabilities = -1,
 	.requester = local_request,
 	.send_digit_begin = local_digit_begin,
 	.send_digit_end = local_digit_end,
@@ -138,15 +137,15 @@ static const struct ast_channel_tech local_tech = {
 
 */
 struct local_pvt {
-	unsigned int flags;                     /*!< Private flags */
-	char context[AST_MAX_CONTEXT];		/*!< Context to call */
-	char exten[AST_MAX_EXTENSION];		/*!< Extension to call */
-	format_t reqformat;				/*!< Requested format */
-	struct ast_jb_conf jb_conf;		/*!< jitterbuffer configuration for this local channel */
-	struct ast_channel *owner;		/*!< Master Channel - Bridging happens here */
-	struct ast_channel *chan;		/*!< Outbound channel - PBX is run here */
-	struct ast_module_user *u_owner;	/*!< reference to keep the module loaded while in use */
-	struct ast_module_user *u_chan;		/*!< reference to keep the module loaded while in use */
+	unsigned int flags;             /*!< Private flags */
+	char context[AST_MAX_CONTEXT];  /*!< Context to call */
+	char exten[AST_MAX_EXTENSION];  /*!< Extension to call */
+	struct ast_format_cap *reqcap;  /*!< Requested format capabilities */
+	struct ast_jb_conf jb_conf;     /*!< jitterbuffer configuration for this local channel */
+	struct ast_channel *owner;      /*!< Master Channel - Bridging happens here */
+	struct ast_channel *chan;       /*!< Outbound channel - PBX is run here */
+	struct ast_module_user *u_owner;/*!< reference to keep the module loaded while in use */
+	struct ast_module_user *u_chan; /*!< reference to keep the module loaded while in use */
 };
 
 #define LOCAL_ALREADY_MASQED  (1 << 0) /*!< Already masqueraded */
@@ -954,13 +953,23 @@ static int local_hangup(struct ast_channel *ast)
 	return 0;
 }
 
+static void local_destroy(void *obj)
+{
+	struct local_pvt *pvt = obj;
+	pvt->reqcap = ast_format_cap_destroy(pvt->reqcap);
+}
+
 /*! \brief Create a call structure */
-static struct local_pvt *local_alloc(const char *data, format_t format)
+static struct local_pvt *local_alloc(const char *data, struct ast_format_cap *cap)
 {
 	struct local_pvt *tmp = NULL;
 	char *c = NULL, *opts = NULL;
 
-	if (!(tmp = ao2_alloc(sizeof(*tmp), NULL))) {
+	if (!(tmp = ao2_alloc(sizeof(*tmp), local_destroy))) {
+		return NULL;
+	}
+	if (!(tmp->reqcap = ast_format_cap_dup(cap))) {
+		ao2_ref(tmp, -1);
 		return NULL;
 	}
 
@@ -995,9 +1004,6 @@ static struct local_pvt *local_alloc(const char *data, format_t format)
 		*c++ = '\0';
 
 	ast_copy_string(tmp->context, c ? c : "default", sizeof(tmp->context));
-
-	tmp->reqformat = format;
-
 #if 0
 	/* We can't do this check here, because we don't know the CallerID yet, and
 	 * the CallerID could potentially affect what step is actually taken (or
@@ -1019,7 +1025,8 @@ static struct local_pvt *local_alloc(const char *data, format_t format)
 static struct ast_channel *local_new(struct local_pvt *p, int state, const char *linkedid)
 {
 	struct ast_channel *tmp = NULL, *tmp2 = NULL;
-	int randnum = ast_random() & 0xffff, fmt = 0;
+	int randnum = ast_random() & 0xffff;
+	struct ast_format fmt;
 	const char *t;
 	int ama;
 
@@ -1045,19 +1052,19 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
 
 	tmp2->tech = tmp->tech = &local_tech;
 
-	tmp->nativeformats = p->reqformat;
-	tmp2->nativeformats = p->reqformat;
+	ast_format_cap_copy(tmp->nativeformats, p->reqcap);
+	ast_format_cap_copy(tmp2->nativeformats, p->reqcap);
 
 	/* Determine our read/write format and set it on each channel */
-	fmt = ast_best_codec(p->reqformat);
-	tmp->writeformat = fmt;
-	tmp2->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	tmp2->rawwriteformat = fmt;
-	tmp->readformat = fmt;
-	tmp2->readformat = fmt;
-	tmp->rawreadformat = fmt;
-	tmp2->rawreadformat = fmt;
+	ast_best_codec(p->reqcap, &fmt);
+	ast_format_copy(&tmp->writeformat, &fmt);
+	ast_format_copy(&tmp2->writeformat, &fmt);
+	ast_format_copy(&tmp->rawwriteformat, &fmt);
+	ast_format_copy(&tmp2->rawwriteformat, &fmt);
+	ast_format_copy(&tmp->readformat, &fmt);
+	ast_format_copy(&tmp2->readformat, &fmt);
+	ast_format_copy(&tmp->rawreadformat, &fmt);
+	ast_format_copy(&tmp2->rawreadformat, &fmt);
 
 	tmp->tech_pvt = p;
 	tmp2->tech_pvt = p;
@@ -1079,13 +1086,13 @@ static struct ast_channel *local_new(struct local_pvt *p, int state, const char
 }
 
 /*! \brief Part of PBX interface */
-static struct ast_channel *local_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *local_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct local_pvt *p = NULL;
 	struct ast_channel *chan = NULL;
 
 	/* Allocate a new private structure and then Asterisk channel */
-	if ((p = local_alloc(data, format))) {
+	if ((p = local_alloc(data, cap))) {
 		if (!(chan = local_new(p, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL))) {
 			ao2_unlink(locals, p);
 		}
@@ -1197,7 +1204,13 @@ static int locals_cmp_cb(void *obj, void *arg, int flags)
 /*! \brief Load module into PBX, register channel */
 static int load_module(void)
 {
+	if (!(local_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add_all(local_tech.capabilities);
+
 	if (!(locals = ao2_container_alloc(BUCKET_SIZE, NULL, locals_cmp_cb))) {
+		ast_format_cap_destroy(local_tech.capabilities);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
@@ -1205,6 +1218,7 @@ static int load_module(void)
 	if (ast_channel_register(&local_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'Local'\n");
 		ao2_ref(locals, -1);
+		ast_format_cap_destroy(local_tech.capabilities);
 		return AST_MODULE_LOAD_FAILURE;
 	}
 	ast_cli_register_multiple(cli_local, sizeof(cli_local) / sizeof(struct ast_cli_entry));
@@ -1234,6 +1248,7 @@ static int unload_module(void)
 	ao2_iterator_destroy(&it);
 	ao2_ref(locals, -1);
 
+	ast_format_cap_destroy(local_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_mgcp.c b/channels/chan_mgcp.c
index 723849785abef5401ba1507d010be8f9eb54d631..32886a6a7b07befd6371446410e93a10d618f099 100644
--- a/channels/chan_mgcp.c
+++ b/channels/chan_mgcp.c
@@ -222,7 +222,7 @@ static pthread_t monitor_thread = AST_PTHREADT_NULL;
 
 static int restart_monitor(void);
 
-static format_t capability = AST_FORMAT_ULAW;
+static struct ast_format_cap *global_capability;
 static int nonCodecCapability = AST_RTP_DTMF;
 
 static char ourhost[MAXHOSTNAMELEN];
@@ -361,7 +361,7 @@ struct mgcp_endpoint {
 	int iseq; /*!< Not used? */
 	int lastout; /*!< tracking this on the subchannels.  Is it needed here? */
 	int needdestroy; /*!< Not used? */
-	format_t capability;
+	struct ast_format_cap *cap;
 	int nonCodecCapability;
 	int onhooktime;
 	int msgstate; /*!< voicemail message state */
@@ -429,7 +429,7 @@ static int transmit_notify_request(struct mgcp_subchannel *sub, char *tone);
 static int transmit_modify_request(struct mgcp_subchannel *sub);
 static int transmit_connect(struct mgcp_subchannel *sub);
 static int transmit_notify_request_with_callerid(struct mgcp_subchannel *sub, char *tone, char *callernum, char *callername);
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs);
+static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, const struct ast_format_cap *codecs);
 static int transmit_connection_del(struct mgcp_subchannel *sub);
 static int transmit_audit_endpoint(struct mgcp_endpoint *p);
 static void start_rtp(struct mgcp_subchannel *sub);
@@ -439,7 +439,7 @@ static void dump_cmd_queues(struct mgcp_endpoint *p, struct mgcp_subchannel *sub
 static char *mgcp_reload(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a);
 static int reload_config(int reload);
 
-static struct ast_channel *mgcp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int mgcp_call(struct ast_channel *ast, char *dest, int timeout);
 static int mgcp_hangup(struct ast_channel *ast);
 static int mgcp_answer(struct ast_channel *ast);
@@ -458,10 +458,9 @@ static int acf_channel_read(struct ast_channel *chan, const char *funcname, char
 static struct ast_variable *add_var(const char *buf, struct ast_variable *list);
 static struct ast_variable *copy_vars(struct ast_variable *src);
 
-static const struct ast_channel_tech mgcp_tech = {
+static struct ast_channel_tech mgcp_tech = {
 	.type = "MGCP",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = mgcp_request,
 	.devicestate = mgcp_devicestate,
@@ -1208,11 +1207,11 @@ static struct ast_frame *mgcp_rtp_read(struct mgcp_subchannel *sub)
 	if (sub->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != sub->owner->nativeformats) {
-				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
-				sub->owner->nativeformats = f->subclass.codec;
-				ast_set_read_format(sub->owner, sub->owner->readformat);
-				ast_set_write_format(sub->owner, sub->owner->writeformat);
+			if (!ast_format_cap_iscompatible(sub->owner->nativeformats, &f->subclass.format)) {
+				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
+				ast_set_read_format(sub->owner, &sub->owner->readformat);
+				ast_set_write_format(sub->owner, &sub->owner->writeformat);
 			}
 			/* Courtesy fearnor aka alex@pilosoft.com */
 			if ((sub->parent->dtmfmode & MGCP_DTMF_INBAND) && (sub->parent->dsp)) {
@@ -1251,12 +1250,12 @@ static int mgcp_write(struct ast_channel *ast, struct ast_frame *frame)
 			return 0;
 		}
 	} else {
-		if (!(frame->subclass.codec & ast->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
 			ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
-				ast_getformatname(frame->subclass.codec),
+				ast_getformatname(&frame->subclass.format),
 				ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
-				ast_getformatname(ast->readformat),
-				ast_getformatname(ast->writeformat));
+				ast_getformatname(&ast->readformat),
+				ast_getformatname(&ast->writeformat));
 			/* return -1; */
 		}
 	}
@@ -1489,16 +1488,15 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
 	struct ast_channel *tmp;
 	struct ast_variable *v = NULL;
 	struct mgcp_endpoint *i = sub->parent;
-	int fmt;
+	struct ast_format tmpfmt;
 
 	tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, linkedid, i->accountcode, i->exten, i->context, i->amaflags, "MGCP/%s@%s-%d", i->name, i->parent->name, sub->id);
 	if (tmp) {
 		tmp->tech = &mgcp_tech;
-		tmp->nativeformats = i->capability;
-		if (!tmp->nativeformats) {
-			tmp->nativeformats = capability;
+		ast_format_cap_copy(tmp->nativeformats, i->cap);
+		if (ast_format_cap_is_empty(tmp->nativeformats)) {
+			ast_format_cap_copy(tmp->nativeformats, global_capability);
 		}
-		fmt = ast_best_codec(tmp->nativeformats);
 		if (sub->rtp) {
 			ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
 		}
@@ -1512,10 +1510,12 @@ static struct ast_channel *mgcp_new(struct mgcp_subchannel *sub, int state, cons
 		}
 		if (state == AST_STATE_RING)
 			tmp->rings = 1;
-		tmp->writeformat = fmt;
-		tmp->rawwriteformat = fmt;
-		tmp->readformat = fmt;
-		tmp->rawreadformat = fmt;
+
+		ast_best_codec(tmp->nativeformats, &tmpfmt);
+		ast_format_copy(&tmp->writeformat, &tmpfmt);
+		ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+		ast_format_copy(&tmp->readformat, &tmpfmt);
+		ast_format_copy(&tmp->rawreadformat, &tmpfmt);
 		tmp->tech_pvt = sub;
 		if (!ast_strlen_zero(i->language))
 			ast_string_field_set(tmp, language, i->language);
@@ -1954,7 +1954,7 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
 	char host[258];
 	int len;
 	int portno;
-	format_t peercapability;
+	struct ast_format_cap *peercap;
 	int peerNonCodecCapability;
 	struct sockaddr_in sin;
 	struct ast_sockaddr sin_tmp;
@@ -2020,15 +2020,20 @@ static int process_sdp(struct mgcp_subchannel *sub, struct mgcp_request *req)
 	}
 
 	/* Now gather all of the codecs that were asked for: */
-	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), &peercapability, &peerNonCodecCapability);
-	p->capability = capability & peercapability;
+	if (!(peercap = ast_format_cap_alloc_nolock())) {
+		return -1;
+	}
+	ast_rtp_codecs_payload_formats(ast_rtp_instance_get_codecs(sub->rtp), peercap, &peerNonCodecCapability);
+	ast_format_cap_joint_copy(global_capability, peercap, p->cap);
 	ast_debug(1, "Capabilities: us - %s, them - %s, combined - %s\n",
-		ast_getformatname_multiple(tmp1, sizeof(tmp1), capability),
-		ast_getformatname_multiple(tmp2, sizeof(tmp2), peercapability),
-		ast_getformatname_multiple(tmp3, sizeof(tmp3), p->capability));
+		ast_getformatname_multiple(tmp1, sizeof(tmp1), global_capability),
+		ast_getformatname_multiple(tmp2, sizeof(tmp2), peercap),
+		ast_getformatname_multiple(tmp3, sizeof(tmp3), p->cap));
+	peercap = ast_format_cap_destroy(peercap);
+
 	ast_debug(1, "Non-codec capabilities: us - %d, them - %d, combined - %d\n",
 		nonCodecCapability, peerNonCodecCapability, p->nonCodecCapability);
-	if (!p->capability) {
+	if (ast_format_cap_is_empty(p->cap)) {
 		ast_log(LOG_WARNING, "No compatible codecs!\n");
 		return -1;
 	}
@@ -2181,7 +2186,8 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
 	char t[256];
 	char m[256] = "";
 	char a[1024] = "";
-	format_t x;
+	int x;
+	struct ast_format tmpfmt;
 	struct sockaddr_in dest = { 0, };
 	struct ast_sockaddr dest_tmp;
 	struct mgcp_endpoint *p = sub->parent;
@@ -2215,30 +2221,34 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
 	snprintf(c, sizeof(c), "c=IN IP4 %s\r\n", ast_inet_ntoa(dest.sin_addr));
 	ast_copy_string(t, "t=0 0\r\n", sizeof(t));
 	snprintf(m, sizeof(m), "m=audio %d RTP/AVP", ntohs(dest.sin_port));
-	for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
-		if (!(x & AST_FORMAT_AUDIO_MASK)) {
+
+	ast_format_cap_iter_start(p->cap);
+	while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+		if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
 			/* Audio is now discontiguous */
 			continue;
 		}
-		if (p->capability & x) {
-			ast_debug(1, "Answering with capability %s\n", ast_getformatname(x));
-			codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, x);
+		if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+			ast_debug(1, "Answering with capability %s\n", ast_getformatname(&tmpfmt));
+			codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &tmpfmt, 0);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, x, 0));
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
 				strncat(a, costr, sizeof(a) - strlen(a) - 1);
 			}
 		}
 	}
+	ast_format_cap_iter_end(p->cap);
+
 	for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
 		if (p->nonCodecCapability & x) {
 			ast_debug(1, "Answering with non-codec capability %d\n", (int) x);
-			codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 0, x);
+			codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 0, NULL, x);
 			if (codec > -1) {
 				snprintf(costr, sizeof(costr), " %d", codec);
 				strncat(m, costr, sizeof(m) - strlen(m) - 1);
-				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, x, 0));
+				snprintf(costr, sizeof(costr), "a=rtpmap:%d %s/8000\r\n", codec, ast_rtp_lookup_mime_subtype2(0, NULL, x, 0));
 				strncat(a, costr, sizeof(a) - strlen(a) - 1);
 				if (x == AST_RTP_DTMF) {
 					/* Indicate we support DTMF...  Not sure about 16,
@@ -2262,13 +2272,13 @@ static int add_sdp(struct mgcp_request *resp, struct mgcp_subchannel *sub, struc
 	return 0;
 }
 
-static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, format_t codecs)
+static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_instance *rtp, const struct ast_format_cap *codecs)
 {
 	struct mgcp_request resp;
 	char local[256];
 	char tmp[80];
 	struct mgcp_endpoint *p = sub->parent;
-	format_t x;
+	struct ast_format tmpfmt;
 	struct ast_sockaddr sub_tmpdest_tmp;
 
 	if (ast_strlen_zero(sub->cxident) && rtp) {
@@ -2279,16 +2289,18 @@ static int transmit_modify_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp_
 		return 0;
 	}
 	ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
-	for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
-		if (!(x & AST_FORMAT_AUDIO_MASK)) {
-			/* No longer contiguous */
+	ast_format_cap_iter_start(p->cap);
+	while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+		if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
+			/* Audio is now discontiguous */
 			continue;
 		}
-		if (p->capability & x) {
-			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+		if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
+	ast_format_cap_iter_end(p->cap);
 
 	if (sub->gate) {
 		if (sub->gate->state == GATE_ALLOCATED || sub->gate->state == GATE_OPEN) {
@@ -2324,7 +2336,7 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
 	struct mgcp_request resp;
 	char local[256];
 	char tmp[80];
-	int x;
+	struct ast_format tmpfmt;
 	struct mgcp_endpoint *p = sub->parent;
 
 	ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
@@ -2332,16 +2344,18 @@ static int transmit_connect_with_sdp(struct mgcp_subchannel *sub, struct ast_rtp
 
 	ast_copy_string(local, "e:on, s:off, p:20", sizeof(local));
 
-	for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
-		if (!(x & AST_FORMAT_AUDIO_MASK)) {
-			/* No longer contiguous */
+	ast_format_cap_iter_start(p->cap);
+	while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+		if (AST_FORMAT_GET_TYPE(tmpfmt.id) != AST_FORMAT_TYPE_AUDIO) {
+			/* Audio is now discontiguous */
 			continue;
 		}
-		if (p->capability & x) {
-			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+		if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
+	ast_format_cap_iter_end(p->cap);
 
 	if (sub->gate) {
 		if(sub->gate->state == GATE_ALLOCATED) {
@@ -2419,17 +2433,19 @@ static int transmit_connect(struct mgcp_subchannel *sub)
 	struct mgcp_request resp;
 	char local[256];
 	char tmp[80];
-	format_t x;
+	struct ast_format tmpfmt;
 	struct mgcp_endpoint *p = sub->parent;
 
 	ast_copy_string(local, "p:20, s:off, e:on", sizeof(local));
 
-	for (x = 1LL; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
-		if (p->capability & x) {
-			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
+	ast_format_cap_iter_start(p->cap);
+	while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+		if (ast_format_cap_iscompatible(p->cap, &tmpfmt)) {
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
 			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 		}
 	}
+	ast_format_cap_iter_end(p->cap);
 
 	ast_debug(3, "Creating connection for %s@%s-%d in cxmode: %s callid: %s\n",
 		    p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
@@ -2522,7 +2538,7 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
 {
 	struct mgcp_request resp;
 	struct mgcp_endpoint *p = sub->parent;
-	format_t x;
+	struct ast_format tmpfmt;
 	int fc = 1;
 	char local[256];
 	char tmp[80];
@@ -2536,18 +2552,18 @@ static int transmit_modify_request(struct mgcp_subchannel *sub)
 		p->name, p->parent->name, sub->id, mgcp_cxmodes[sub->cxmode], sub->callid);
 
 	ast_copy_string(local, "", sizeof(local));
-	for (x = 1; x <= AST_FORMAT_AUDIO_MASK; x <<= 1) {
-		if (p->capability & x) {
-			if (p->ncs && !fc) {
-				p->capability = x; /* sb5120e bug */
-				break;
-			} else {
-				fc = 0;
-				snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, x, 0));
-			}
-			strncat(local, tmp, sizeof(local) - strlen(local) - 1);
+	ast_format_cap_iter_start(p->cap);
+	while (!(ast_format_cap_iter_next(p->cap, &tmpfmt))) {
+		if (p->ncs && !fc) {
+			ast_format_cap_set(p->cap, &tmpfmt); /* sb5120e bug */
+			break;
+		} else {
+			fc = 0;
+			snprintf(tmp, sizeof(tmp), ", a:%s", ast_rtp_lookup_mime_subtype2(1, &tmpfmt, 0, 0));
 		}
+		strncat(local, tmp, sizeof(local) - strlen(local) - 1);
 	}
+	ast_format_cap_iter_end(p->cap);
 
 	if (!sub->sdpsent) {
 		if (sub->gate) {
@@ -3899,18 +3915,15 @@ static int restart_monitor(void)
 	return 0;
 }
 
-static struct ast_channel *mgcp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *mgcp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat;
 	struct mgcp_subchannel *sub;
 	struct ast_channel *tmpc = NULL;
 	char tmp[256];
 	char *dest = data;
 
-	oldformat = format;
-	format &= capability;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
+	if (!(ast_format_cap_has_joint(cap, global_capability))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		/*return NULL;*/
 	}
 	ast_copy_string(tmp, dest, sizeof(tmp));
@@ -4138,6 +4151,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
 					ast_mutex_init(&e->lock);
 					ast_mutex_init(&e->rqnt_queue_lock);
 					ast_mutex_init(&e->cmd_queue_lock);
+					e->cap = ast_format_cap_alloc_nolock();
 					ast_copy_string(e->name, v->value, sizeof(e->name));
 					e->needaudit = 1;
 				}
@@ -4167,7 +4181,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
 				snprintf(e->rqnt_ident, sizeof(e->rqnt_ident), "%08lx", ast_random());
 				e->msgstate = -1;
 				e->amaflags = amaflags;
-				e->capability = capability;
+				ast_format_cap_copy(e->cap, global_capability);
 				e->parent = gw;
 				e->ncs = ncs;
 				e->dtmfmode = dtmfmode;
@@ -4249,6 +4263,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
 					ast_mutex_init(&e->lock);
 					ast_mutex_init(&e->rqnt_queue_lock);
 					ast_mutex_init(&e->cmd_queue_lock);
+					e->cap = ast_format_cap_alloc_nolock();
 					ast_copy_string(e->name, v->value, sizeof(e->name));
 					e->needaudit = 1;
 				}
@@ -4270,7 +4285,7 @@ static struct mgcp_gateway *build_gateway(char *cat, struct ast_variable *v)
 					e->parent = gw;
 				}
 				e->amaflags = amaflags;
-				e->capability = capability;
+				ast_format_cap_copy(e->cap, global_capability);
 				e->dtmfmode = dtmfmode;
 				e->ncs = ncs;
 				e->pktcgatealloc = pktcgatealloc;
@@ -4410,23 +4425,23 @@ static enum ast_rtp_glue_result mgcp_get_rtp_peer(struct ast_channel *chan, stru
 		return AST_RTP_GLUE_RESULT_LOCAL;
 }
 
-static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+static int mgcp_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *cap, int nat_active)
 {
 	/* XXX Is there such thing as video support with MGCP? XXX */
 	struct mgcp_subchannel *sub;
 	sub = chan->tech_pvt;
 	if (sub && !sub->alreadygone) {
-		transmit_modify_with_sdp(sub, rtp, codecs);
+		transmit_modify_with_sdp(sub, rtp, cap);
 		return 0;
 	}
 	return -1;
 }
 
-static format_t mgcp_get_codec(struct ast_channel *chan)
+static void mgcp_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
 	struct mgcp_subchannel *sub = chan->tech_pvt;
 	struct mgcp_endpoint *p = sub->parent;
-	return p->capability;
+	ast_format_cap_copy(result, p->cap);
 }
 
 static struct ast_rtp_glue mgcp_rtp_glue = {
@@ -4511,6 +4526,7 @@ static void destroy_endpoint(struct mgcp_endpoint *e)
 	ast_mutex_destroy(&e->lock);
 	ast_mutex_destroy(&e->rqnt_queue_lock);
 	ast_mutex_destroy(&e->cmd_queue_lock);
+	e->cap = ast_format_cap_destroy(e->cap);
 	ast_free(e);
 }
 
@@ -4608,7 +4624,7 @@ static int reload_config(int reload)
 	char *cat;
 	struct ast_hostent ahp;
 	struct hostent *hp;
-	int format;
+	struct ast_format format;
 	struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
 	
 	if (gethostname(ourhost, sizeof(ourhost)-1)) {
@@ -4648,18 +4664,18 @@ static int reload_config(int reload)
 				memcpy(&bindaddr.sin_addr, hp->h_addr, sizeof(bindaddr.sin_addr));
 			}
 		} else if (!strcasecmp(v->name, "allow")) {
-			format = ast_getformatbyname(v->value);
-			if (format < 1) {
+			ast_getformatbyname(v->value, &format);
+			if (!format.id) {
 				ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
 			} else {
-				capability |= format;
+				ast_format_cap_add(global_capability, &format);
 			}
 		} else if (!strcasecmp(v->name, "disallow")) {
-			format = ast_getformatbyname(v->value);
-			if (format < 1) {
-				ast_log(LOG_WARNING, "Cannot disallow unknown format '%s'\n", v->value);
+			ast_getformatbyname(v->value, &format);
+			if (!format.id) {
+				ast_log(LOG_WARNING, "Cannot allow unknown format '%s'\n", v->value);
 			} else {
-				capability &= ~format;
+				ast_format_cap_remove(global_capability, &format);
 			}
 		} else if (!strcasecmp(v->name, "tos")) {
 			if (ast_str2tos(v->value, &qos.tos)) {
@@ -4776,6 +4792,17 @@ static int reload_config(int reload)
 /*! \brief  load_module: PBX load module - initialization ---*/
 static int load_module(void)
 {
+	struct ast_format tmpfmt;
+
+	if (!(global_capability = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	if (!(mgcp_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add(global_capability, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(mgcp_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
 	if (!(sched = ast_sched_context_create())) {
 		ast_log(LOG_WARNING, "Unable to create schedule context\n");
 		return AST_MODULE_LOAD_FAILURE;
@@ -4907,6 +4934,9 @@ static int unload_module(void)
 	ast_cli_unregister_multiple(cli_mgcp, sizeof(cli_mgcp) / sizeof(struct ast_cli_entry));
 	ast_sched_context_destroy(sched);
 
+	global_capability = ast_format_cap_destroy(global_capability);
+	mgcp_tech.capabilities = ast_format_cap_destroy(mgcp_tech.capabilities);
+
 	return 0;
 }
 
diff --git a/channels/chan_misdn.c b/channels/chan_misdn.c
index 97eaba942957356cd908d2c580654026f41fe2db..91bcf87035b333b65dfdff4e80579984c1a75f92 100644
--- a/channels/chan_misdn.c
+++ b/channels/chan_misdn.c
@@ -90,6 +90,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/stringfields.h"
 #include "asterisk/abstract_jb.h"
 #include "asterisk/causes.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
 
 #include "chan_misdn_config.h"
 #include "isdn_lib.h"
@@ -645,7 +647,7 @@ static int *misdn_ports;
 static void chan_misdn_log(int level, int port, char *tmpl, ...)
 	__attribute__((format(printf, 3, 4)));
 
-static struct ast_channel *misdn_new(struct chan_list *cl, int state,  char *exten, char *callerid, int format, const char *linkedid, int port, int c);
+static struct ast_channel *misdn_new(struct chan_list *cl, int state,  char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c);
 static void send_digit_to_chan(struct chan_list *cl, char digit);
 
 static int pbx_start_chan(struct chan_list *ch);
@@ -661,7 +663,7 @@ static const char misdn_type[] = "mISDN";
 static int tracing = 0;
 
 /*! \brief Only alaw and mulaw is allowed for now */
-static int prefformat =  AST_FORMAT_ALAW ; /*  AST_FORMAT_SLINEAR ;  AST_FORMAT_ULAW | */
+static struct ast_format prefformat; /*  AST_FORMAT_SLINEAR ;  AST_FORMAT_ULAW | */
 
 static int *misdn_debug;
 static int *misdn_debug_only;
@@ -7346,7 +7348,7 @@ static struct ast_frame *misdn_read(struct ast_channel *ast)
 	}
 
 	tmp->frame.frametype = AST_FRAME_VOICE;
-	tmp->frame.subclass.codec = AST_FORMAT_ALAW;
+	ast_format_set(&tmp->frame.subclass.format, AST_FORMAT_ALAW, 0);
 	tmp->frame.datalen = len;
 	tmp->frame.samples = len;
 	tmp->frame.mallocd = 0;
@@ -7412,13 +7414,13 @@ static int misdn_write(struct ast_channel *ast, struct ast_frame *frame)
 	}
 
 
-	if (!frame->subclass.codec) {
+	if (!frame->subclass.format.id) {
 		chan_misdn_log(4, ch->bc->port, "misdn_write: * prods us\n");
 		return 0;
 	}
 
-	if (!(frame->subclass.codec & prefformat)) {
-		chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(frame->subclass.codec));
+	if (ast_format_cmp(&frame->subclass.format, &prefformat) == AST_FORMAT_CMP_NOT_EQUAL) {
+		chan_misdn_log(-1, ch->bc->port, "Got Unsupported Frame with Format:%s\n", ast_getformatname(&frame->subclass.format));
 		return 0;
 	}
 
@@ -7756,7 +7758,7 @@ static struct chan_list *chan_list_init(int orig)
 	return cl;
 }
 
-static struct ast_channel *misdn_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *misdn_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct ast_channel *ast;
 	char group[BUFFERSIZE + 1] = "";
@@ -7982,7 +7984,7 @@ static struct ast_channel *misdn_request(const char *type, format_t format, cons
 	}
 	cl->bc = newbc;
 
-	ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, format, requestor ? requestor->linkedid : NULL, port, channel);
+	ast = misdn_new(cl, AST_STATE_RESERVED, args.ext, NULL, cap, requestor ? requestor->linkedid : NULL, port, channel);
 	if (!ast) {
 		chan_list_unref(cl, "Failed to create a new channel");
 		ast_log(LOG_ERROR, "Could not create Asterisk channel for Dial(%s)\n", dial_str);
@@ -8025,7 +8027,6 @@ static int misdn_send_text(struct ast_channel *chan, const char *text)
 static struct ast_channel_tech misdn_tech = {
 	.type = misdn_type,
 	.description = "Channel driver for mISDN Support (Bri/Pri)",
-	.capabilities = AST_FORMAT_ALAW ,
 	.requester = misdn_request,
 	.send_digit_begin = misdn_digit_begin,
 	.send_digit_end = misdn_digit_end,
@@ -8044,7 +8045,6 @@ static struct ast_channel_tech misdn_tech = {
 static struct ast_channel_tech misdn_tech_wo_bridge = {
 	.type = misdn_type,
 	.description = "Channel driver for mISDN Support (Bri/Pri)",
-	.capabilities = AST_FORMAT_ALAW ,
 	.requester = misdn_request,
 	.send_digit_begin = misdn_digit_begin,
 	.send_digit_end = misdn_digit_end,
@@ -8086,7 +8086,7 @@ static void update_name(struct ast_channel *tmp, int port, int c)
 	}
 }
 
-static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char *exten, char *callerid, int format, const char *linkedid, int port, int c)
+static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char *exten, char *callerid, struct ast_format_cap *cap, const char *linkedid, int port, int c)
 {
 	struct ast_channel *tmp;
 	char *cid_name = NULL;
@@ -8094,6 +8094,7 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
 	int chan_offset = 0;
 	int tmp_port = misdn_cfg_get_next_port(0);
 	int bridging;
+	struct ast_format tmpfmt;
 
 	for (; tmp_port > 0; tmp_port = misdn_cfg_get_next_port(tmp_port)) {
 		if (tmp_port == port) {
@@ -8113,12 +8114,12 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
 	if (tmp) {
 		chan_misdn_log(2, 0, " --> * NEW CHANNEL dialed:%s caller:%s\n", exten, callerid);
 
-		tmp->nativeformats = prefformat;
-
-		tmp->readformat = format;
-		tmp->rawreadformat = format;
-		tmp->writeformat = format;
-		tmp->rawwriteformat = format;
+		ast_best_codec(cap, &tmpfmt);
+		ast_format_cap_add(tmp->nativeformats, &prefformat);
+		ast_format_copy(&tmp->writeformat, &tmpfmt);
+		ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+		ast_format_copy(&tmp->readformat, &tmpfmt);
+		ast_format_copy(&tmp->rawreadformat, &tmpfmt);
 
 		/* Link the channel and private together */
 		chan_list_ref(chlist, "Give a reference to ast_channel");
@@ -8128,8 +8129,6 @@ static struct ast_channel *misdn_new(struct chan_list *chlist, int state,  char
 		misdn_cfg_get(0, MISDN_GEN_BRIDGING, &bridging, sizeof(bridging));
 		tmp->tech = bridging ? &misdn_tech : &misdn_tech_wo_bridge;
 
-		tmp->writeformat = format;
-		tmp->readformat = format;
 		tmp->priority = 1;
 
 		if (exten) {
@@ -10116,7 +10115,16 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 		ch->l3id = bc->l3_id;
 		ch->addr = bc->addr;
 
-		chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, AST_FORMAT_ALAW, NULL, bc->port, bc->channel);
+		{
+			struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+			struct ast_format tmpfmt;
+			if (!(cap)) {
+				return RESPONSE_ERR; 
+			}
+			ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+			chan = misdn_new(ch, AST_STATE_RESERVED, bc->dialed.number, bc->caller.number, cap, NULL, bc->port, bc->channel);
+			cap = ast_format_cap_destroy(cap);
+		}
 		if (!chan) {
 			chan_list_unref(ch, "Failed to create a new channel");
 			misdn_lib_send_event(bc,EVENT_RELEASE_COMPLETE);
@@ -10723,7 +10731,7 @@ cb_events(enum event_e event, struct misdn_bchannel *bc, void *user_data)
 			/* In Data Modes we queue frames */
 			memset(&frame, 0, sizeof(frame));
 			frame.frametype = AST_FRAME_VOICE; /* we have no data frames yet */
-			frame.subclass.codec = AST_FORMAT_ALAW;
+			ast_format_set(&frame.subclass.format, AST_FORMAT_ALAW, 0);
 			frame.datalen = bc->bframe_len;
 			frame.samples = bc->bframe_len;
 			frame.mallocd = 0;
@@ -11145,6 +11153,8 @@ static int unload_module(void)
 #if defined(AST_MISDN_ENHANCEMENTS)
 	misdn_cc_destroy();
 #endif	/* defined(AST_MISDN_ENHANCEMENTS) */
+	misdn_tech.capabilities = ast_format_cap_destroy(misdn_tech.capabilities);
+	misdn_tech_wo_bridge.capabilities = ast_format_cap_destroy(misdn_tech_wo_bridge.capabilities);
 
 	return 0;
 }
@@ -11162,6 +11172,17 @@ static int load_module(void)
 		.cb_jb_empty = chan_misdn_jb_empty,
 	};
 
+
+	if (!(misdn_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(misdn_tech_wo_bridge.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_set(&prefformat, AST_FORMAT_ALAW, 0);
+	ast_format_cap_add(misdn_tech.capabilities, &prefformat);
+	ast_format_cap_add(misdn_tech_wo_bridge.capabilities, &prefformat);
+
 	max_ports = misdn_lib_maxports_get();
 
 	if (max_ports <= 0) {
diff --git a/channels/chan_multicast_rtp.c b/channels/chan_multicast_rtp.c
index 55b757567fc926a07b9df9112b7647d7b0284d01..b398abb21375ebc616724f5b94c6960e7d87a5d3 100644
--- a/channels/chan_multicast_rtp.c
+++ b/channels/chan_multicast_rtp.c
@@ -52,17 +52,16 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 static const char tdesc[] = "Multicast RTP Paging Channel Driver";
 
 /* Forward declarations */
-static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int multicast_rtp_call(struct ast_channel *ast, char *dest, int timeout);
 static int multicast_rtp_hangup(struct ast_channel *ast);
 static struct ast_frame *multicast_rtp_read(struct ast_channel *ast);
 static int multicast_rtp_write(struct ast_channel *ast, struct ast_frame *f);
 
 /* Channel driver declaration */
-static const struct ast_channel_tech multicast_rtp_tech = {
+static struct ast_channel_tech multicast_rtp_tech = {
 	.type = "MulticastRTP",
 	.description = tdesc,
-	.capabilities = -1,
 	.requester = multicast_rtp_request,
 	.call = multicast_rtp_call,
 	.hangup = multicast_rtp_hangup,
@@ -107,14 +106,15 @@ static int multicast_rtp_hangup(struct ast_channel *ast)
 }
 
 /*! \brief Function called when we should prepare to call the destination */
-static struct ast_channel *multicast_rtp_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *multicast_rtp_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	char *tmp = ast_strdupa(data), *multicast_type = tmp, *destination, *control;
 	struct ast_rtp_instance *instance;
 	struct ast_sockaddr control_address;
 	struct ast_sockaddr destination_address;
 	struct ast_channel *chan;
-	format_t fmt = ast_best_codec(format);
+	struct ast_format fmt;
+	ast_best_codec(cap, &fmt);
 
 	ast_sockaddr_setnull(&control_address);
 
@@ -153,11 +153,13 @@ static struct ast_channel *multicast_rtp_request(const char *type, format_t form
 	ast_rtp_instance_set_remote_address(instance, &destination_address);
 
 	chan->tech = &multicast_rtp_tech;
-	chan->nativeformats = fmt;
-	chan->writeformat = fmt;
-	chan->readformat = fmt;
-	chan->rawwriteformat = fmt;
-	chan->rawreadformat = fmt;
+
+	ast_format_cap_add(chan->nativeformats, &fmt);
+	ast_format_copy(&chan->writeformat, &fmt);
+	ast_format_copy(&chan->rawwriteformat, &fmt);
+	ast_format_copy(&chan->readformat, &fmt);
+	ast_format_copy(&chan->rawreadformat, &fmt);
+
 	chan->tech_pvt = instance;
 
 	return chan;
@@ -170,6 +172,10 @@ failure:
 /*! \brief Function called when our module is loaded */
 static int load_module(void)
 {
+	if (!(multicast_rtp_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add_all(multicast_rtp_tech.capabilities);
 	if (ast_channel_register(&multicast_rtp_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class 'MulticastRTP'\n");
 		return AST_MODULE_LOAD_DECLINE;
@@ -182,6 +188,7 @@ static int load_module(void)
 static int unload_module(void)
 {
 	ast_channel_unregister(&multicast_rtp_tech);
+	multicast_rtp_tech.capabilities = ast_format_cap_destroy(multicast_rtp_tech.capabilities);
 
 	return 0;
 }
diff --git a/channels/chan_nbs.c b/channels/chan_nbs.c
index 882258f00ffda4f7f405803860bb6f813e2f71b1..1cd3d75fb3edf643ae255e2b34f32fa904426f89 100644
--- a/channels/chan_nbs.c
+++ b/channels/chan_nbs.c
@@ -50,7 +50,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 static const char tdesc[] = "Network Broadcast Sound Driver";
 
 /* Only linear is allowed */
-static format_t prefformat = AST_FORMAT_SLINEAR;
+static struct ast_format prefformat;
 
 static char context[AST_MAX_EXTENSION] = "default";
 static const char type[] = "NBS";
@@ -66,16 +66,15 @@ struct nbs_pvt {
 	struct ast_module_user *u;		/*! for holding a reference to this module */
 };
 
-static struct ast_channel *nbs_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int nbs_call(struct ast_channel *ast, char *dest, int timeout);
 static int nbs_hangup(struct ast_channel *ast);
 static struct ast_frame *nbs_xread(struct ast_channel *ast);
 static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame);
 
-static const struct ast_channel_tech nbs_tech = {
+static struct ast_channel_tech nbs_tech = {
 	.type = type,
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR,
 	.requester = nbs_request,
 	.call = nbs_call,
 	.hangup = nbs_hangup,
@@ -205,9 +204,8 @@ static int nbs_xwrite(struct ast_channel *ast, struct ast_frame *frame)
 			ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
 		return 0;
 	}
-	if (!(frame->subclass.codec &
-		(AST_FORMAT_SLINEAR))) {
-		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
+	if (frame->subclass.format.id != (AST_FORMAT_SLINEAR)) {
+		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
 		return 0;
 	}
 	if (ast->_state != AST_STATE_UP) {
@@ -226,11 +224,12 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *lin
 	if (tmp) {
 		tmp->tech = &nbs_tech;
 		ast_channel_set_fd(tmp, 0, nbs_fd(i->nbs));
-		tmp->nativeformats = prefformat;
-		tmp->rawreadformat = prefformat;
-		tmp->rawwriteformat = prefformat;
-		tmp->writeformat = prefformat;
-		tmp->readformat = prefformat;
+
+		ast_format_cap_add(tmp->nativeformats, &prefformat);
+		ast_format_copy(&tmp->rawreadformat, &prefformat);
+		ast_format_copy(&tmp->rawwriteformat, &prefformat);
+		ast_format_copy(&tmp->writeformat, &prefformat);
+		ast_format_copy(&tmp->readformat, &prefformat);
 		if (state == AST_STATE_RING)
 			tmp->rings = 1;
 		tmp->tech_pvt = i;
@@ -251,16 +250,14 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state, const char *lin
 }
 
 
-static struct ast_channel *nbs_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *nbs_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat;
 	struct nbs_pvt *p;
 	struct ast_channel *tmp = NULL;
-	
-	oldformat = format;
-	format &= (AST_FORMAT_SLINEAR);
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
+
+	if (!(ast_format_cap_iscompatible(cap, &prefformat))) {
+		char tmp[256];
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		return NULL;
 	}
 	p = nbs_alloc(data);
@@ -276,11 +273,17 @@ static int unload_module(void)
 {
 	/* First, take us out of the channel loop */
 	ast_channel_unregister(&nbs_tech);
+	nbs_tech.capabilities = ast_format_cap_destroy(nbs_tech.capabilities);
 	return 0;
 }
 
 static int load_module(void)
 {
+	ast_format_set(&prefformat, AST_FORMAT_SLINEAR, 0);
+	if (!(nbs_tech.capabilities == ast_format_cap_alloc())) {
+		return -1;
+	}
+	ast_format_cap_add(nbs_tech.capabilities, &prefformat);
 	/* Make sure we can register our channel type */
 	if (ast_channel_register(&nbs_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel class %s\n", type);
diff --git a/channels/chan_oss.c b/channels/chan_oss.c
index 3c4f2c943ee8a39960d41544c790e62495929d1a..10b0ed0fd52d89cfebc551fe76ad6e42e220aeae 100644
--- a/channels/chan_oss.c
+++ b/channels/chan_oss.c
@@ -326,7 +326,7 @@ static struct chan_oss_pvt oss_default = {
 
 static int setformat(struct chan_oss_pvt *o, int mode);
 
-static struct ast_channel *oss_request(const char *type, format_t format, const struct ast_channel *requestor,
+static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor,
 									   void *data, int *cause);
 static int oss_digit_begin(struct ast_channel *c, char digit);
 static int oss_digit_end(struct ast_channel *c, char digit, unsigned int duration);
@@ -344,7 +344,6 @@ static char tdesc[] = "OSS Console Channel Driver";
 static struct ast_channel_tech oss_tech = {
 	.type = "Console",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR, /* overwritten later */
 	.requester = oss_request,
 	.send_digit_begin = oss_digit_begin,
 	.send_digit_end = oss_digit_end,
@@ -719,7 +718,7 @@ static struct ast_frame *oss_read(struct ast_channel *c)
 		return f;
 	/* ok we can build and deliver the frame to the caller */
 	f->frametype = AST_FRAME_VOICE;
-	f->subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&f->subclass.format, AST_FORMAT_SLINEAR, 0);
 	f->samples = FRAME_SIZE;
 	f->datalen = FRAME_SIZE * 2;
 	f->data.ptr = o->oss_read_buf + AST_FRIENDLY_OFFSET;
@@ -794,13 +793,15 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
 	if (o->sounddev < 0)
 		setformat(o, O_RDWR);
 	ast_channel_set_fd(c, 0, o->sounddev); /* -1 if device closed, override later */
-	c->nativeformats = AST_FORMAT_SLINEAR;
+
+	ast_format_set(&c->readformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&c->writeformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_cap_add(c->nativeformats, &c->readformat);
+
 	/* if the console makes the call, add video to the offer */
-	if (state == AST_STATE_RINGING)
-		c->nativeformats |= console_video_formats;
+	/* if (state == AST_STATE_RINGING) TODO XXX CONSOLE VIDEO IS DISABLED UNTIL IT GETS A MAINTAINER
+		c->nativeformats |= console_video_formats; */
 
-	c->readformat = AST_FORMAT_SLINEAR;
-	c->writeformat = AST_FORMAT_SLINEAR;
 	c->tech_pvt = o;
 
 	if (!ast_strlen_zero(o->language))
@@ -830,7 +831,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx,
 	return c;
 }
 
-static struct ast_channel *oss_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *oss_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct ast_channel *c;
 	struct chan_oss_pvt *o;
@@ -840,6 +841,7 @@ static struct ast_channel *oss_request(const char *type, format_t format, const
 	);
 	char *parse = ast_strdupa(data);
 	char buf[256];
+	struct ast_format tmpfmt;
 
 	AST_NONSTANDARD_APP_ARGS(args, parse, '/');
 	o = find_desc(args.name);
@@ -850,8 +852,8 @@ static struct ast_channel *oss_request(const char *type, format_t format, const
 		/* XXX we could default to 'dsp' perhaps ? */
 		return NULL;
 	}
-	if ((format & AST_FORMAT_SLINEAR) == 0) {
-		ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_getformatname_multiple(buf, sizeof(buf), format));
+	if (!(ast_format_cap_iscompatible(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0)))) {
+		ast_log(LOG_NOTICE, "Format %s unsupported\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
 		return NULL;
 	}
 	if (o->owner) {
@@ -1437,6 +1439,7 @@ static int load_module(void)
 	struct ast_config *cfg = NULL;
 	char *ctg = NULL;
 	struct ast_flags config_flags = { 0 };
+	struct ast_format tmpfmt;
 
 	/* Copy the default jb config over global_jbconf */
 	memcpy(&global_jbconf, &default_jbconf, sizeof(struct ast_jb_conf));
@@ -1463,7 +1466,13 @@ static int load_module(void)
 		return AST_MODULE_LOAD_FAILURE;
 	}
 
-	oss_tech.capabilities |= console_video_formats;
+	if (!(oss_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add(oss_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+
+	/* TODO XXX CONSOLE VIDEO IS DISABLE UNTIL IT HAS A MAINTAINER
+	 * add console_video_formats to oss_tech.capabilities once this occurs. */
 
 	if (ast_channel_register(&oss_tech)) {
 		ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n");
@@ -1495,6 +1504,7 @@ static int unload_module(void)
 		ast_free(o);
 		o = next;
 	}
+	oss_tech.capabilities = ast_format_cap_destroy(oss_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_phone.c b/channels/chan_phone.c
index 531b95cb56af5c0da639d686d60dbca2006dd1d0..4897775cc41dca6dc0d451e29878354a1ffdb6f5 100644
--- a/channels/chan_phone.c
+++ b/channels/chan_phone.c
@@ -94,7 +94,7 @@ static int echocancel = AEC_OFF;
 
 static int silencesupression = 0;
 
-static format_t prefformat = AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW;
+static struct ast_format_cap *prefcap;
 
 /* Protect the interface list (of phone_pvt's) */
 AST_MUTEX_DEFINE_STATIC(iflock);
@@ -125,8 +125,8 @@ static struct phone_pvt {
 	int fd;							/* Raw file descriptor for this device */
 	struct ast_channel *owner;		/* Channel we belong to, possibly NULL */
 	int mode;						/* Is this in the  */
-	format_t lastformat;            /* Last output format */
-	format_t lastinput;             /* Last input format */
+	struct ast_format lastformat;            /* Last output format */
+	struct ast_format lastinput;             /* Last input format */
 	int ministate;					/* Miniature state, for dialtone mode */
 	char dev[256];					/* Device name */
 	struct phone_pvt *next;			/* Next channel in list */
@@ -150,7 +150,7 @@ static struct phone_pvt {
 static char cid_num[AST_MAX_EXTENSION];
 static char cid_name[AST_MAX_EXTENSION];
 
-static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int phone_digit_begin(struct ast_channel *ast, char digit);
 static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int phone_call(struct ast_channel *ast, char *dest, int timeout);
@@ -163,10 +163,9 @@ static int phone_send_text(struct ast_channel *ast, const char *text);
 static int phone_fixup(struct ast_channel *old, struct ast_channel *new);
 static int phone_indicate(struct ast_channel *chan, int condition, const void *data, size_t datalen);
 
-static const struct ast_channel_tech phone_tech = {
+static struct ast_channel_tech phone_tech = {
 	.type = "Phone",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A,
 	.requester = phone_request,
 	.send_digit_begin = phone_digit_begin,
 	.send_digit_end = phone_digit_end,
@@ -210,9 +209,9 @@ static int phone_indicate(struct ast_channel *chan, int condition, const void *d
 		ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
 		usleep(320000);
 		ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
-			p->lastformat = -1;
-			res = 0;
-			break;
+		ast_format_clear(&p->lastformat);
+		res = 0;
+		break;
 	case AST_CONTROL_HOLD:
 		ast_moh_start(chan, data, NULL);
 		break;
@@ -272,7 +271,7 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
 		ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_ON_HOOK);
 		usleep(320000);
 		ioctl(p->fd, IXJCTL_PSTN_SET_STATE, PSTN_OFF_HOOK);
-		p->lastformat = -1;
+		ast_format_clear(&p->lastformat);
 		return 0;
 	default:
 		ast_log(LOG_WARNING, "Unknown digit '%c'\n", digit);
@@ -280,7 +279,7 @@ static int phone_digit_end(struct ast_channel *ast, char digit, unsigned int dur
 	}
 	ast_debug(1, "Dialed %d\n", outdigit);
 	ioctl(p->fd, PHONE_PLAY_TONE, outdigit);
-	p->lastformat = -1;
+	ast_format_clear(&p->lastformat);
 	return 0;
 }
 
@@ -373,8 +372,8 @@ static int phone_hangup(struct ast_channel *ast)
 		ioctl(p->fd, PHONE_BUSY);
 		p->cpt = 1;
 	}
-	p->lastformat = -1;
-	p->lastinput = -1;
+	ast_format_clear(&p->lastformat);
+	ast_format_clear(&p->lastinput);
 	p->ministate = 0;
 	p->obuflen = 0;
 	p->dialtone = 0;
@@ -394,38 +393,38 @@ static int phone_setup(struct ast_channel *ast)
 	p = ast->tech_pvt;
 	ioctl(p->fd, PHONE_CPT_STOP);
 	/* Nothing to answering really, just start recording */
-	if (ast->rawreadformat == AST_FORMAT_G729A) {
+	if (ast->rawreadformat.id == AST_FORMAT_G729A) {
 		/* Prefer g729 */
 		ioctl(p->fd, PHONE_REC_STOP);
-		if (p->lastinput != AST_FORMAT_G729A) {
-			p->lastinput = AST_FORMAT_G729A;
+		if (p->lastinput.id != AST_FORMAT_G729A) {
+			ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
 			if (ioctl(p->fd, PHONE_REC_CODEC, G729)) {
 				ast_log(LOG_WARNING, "Failed to set codec to g729\n");
 				return -1;
 			}
 		}
-        } else if (ast->rawreadformat == AST_FORMAT_G723_1) {
+        } else if (ast->rawreadformat.id == AST_FORMAT_G723_1) {
 		ioctl(p->fd, PHONE_REC_STOP);
-		if (p->lastinput != AST_FORMAT_G723_1) {
-			p->lastinput = AST_FORMAT_G723_1;
+		if (p->lastinput.id != AST_FORMAT_G723_1) {
+			ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
 			if (ioctl(p->fd, PHONE_REC_CODEC, G723_63)) {
 				ast_log(LOG_WARNING, "Failed to set codec to g723.1\n");
 				return -1;
 			}
 		}
-	} else if (ast->rawreadformat == AST_FORMAT_SLINEAR) {
+	} else if (ast->rawreadformat.id == AST_FORMAT_SLINEAR) {
 		ioctl(p->fd, PHONE_REC_STOP);
-		if (p->lastinput != AST_FORMAT_SLINEAR) {
-			p->lastinput = AST_FORMAT_SLINEAR;
+		if (p->lastinput.id != AST_FORMAT_SLINEAR) {
+			ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
 			if (ioctl(p->fd, PHONE_REC_CODEC, LINEAR16)) {
 				ast_log(LOG_WARNING, "Failed to set codec to signed linear 16\n");
 				return -1;
 			}
 		}
-	} else if (ast->rawreadformat == AST_FORMAT_ULAW) {
+	} else if (ast->rawreadformat.id == AST_FORMAT_ULAW) {
 		ioctl(p->fd, PHONE_REC_STOP);
-		if (p->lastinput != AST_FORMAT_ULAW) {
-			p->lastinput = AST_FORMAT_ULAW;
+		if (p->lastinput.id != AST_FORMAT_ULAW) {
+			ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
 			if (ioctl(p->fd, PHONE_REC_CODEC, ULAW)) {
 				ast_log(LOG_WARNING, "Failed to set codec to uLaw\n");
 				return -1;
@@ -433,16 +432,16 @@ static int phone_setup(struct ast_channel *ast)
 		}
 	} else if (p->mode == MODE_FXS) {
 		ioctl(p->fd, PHONE_REC_STOP);
-		if (p->lastinput != ast->rawreadformat) {
-			p->lastinput = ast->rawreadformat;
-			if (ioctl(p->fd, PHONE_REC_CODEC, ast->rawreadformat)) {
+		if (ast_format_cmp(&p->lastinput, &ast->rawreadformat) == AST_FORMAT_CMP_NOT_EQUAL) {
+			ast_format_copy(&p->lastinput, &ast->rawreadformat);
+			if (ioctl(p->fd, PHONE_REC_CODEC, &ast->rawreadformat)) {
 				ast_log(LOG_WARNING, "Failed to set codec to %s\n", 
-					ast_getformatname(ast->rawreadformat));
+					ast_getformatname(&ast->rawreadformat));
 				return -1;
 			}
 		}
 	} else {
-		ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(ast->rawreadformat));
+		ast_log(LOG_WARNING, "Can't do format %s\n", ast_getformatname(&ast->rawreadformat));
 		return -1;
 	}
 	if (ioctl(p->fd, PHONE_REC_START)) {
@@ -593,14 +592,13 @@ static struct ast_frame  *phone_read(struct ast_channel *ast)
 	}
 	p->fr.samples = 240;
 	p->fr.datalen = res;
-	p->fr.frametype = p->lastinput <= AST_FORMAT_AUDIO_MASK ?
-                          AST_FRAME_VOICE : 
-			  p->lastinput <= AST_FORMAT_PNG ? AST_FRAME_IMAGE 
-			  : AST_FRAME_VIDEO;
-	p->fr.subclass.codec = p->lastinput;
+	p->fr.frametype = AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_AUDIO ?
+		AST_FRAME_VOICE : AST_FORMAT_GET_TYPE(p->lastinput.id) == AST_FORMAT_TYPE_IMAGE ?
+		AST_FRAME_IMAGE : AST_FRAME_VIDEO;
+	ast_format_copy(&p->fr.subclass.format, &p->lastinput);
 	p->fr.offset = AST_FRIENDLY_OFFSET;
 	/* Byteswap from little-endian to native-endian */
-	if (p->fr.subclass.codec == AST_FORMAT_SLINEAR)
+	if (p->fr.subclass.format.id == AST_FORMAT_SLINEAR)
 		ast_frame_byteswap_le(&p->fr);
 	return &p->fr;
 }
@@ -662,10 +660,12 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 			ast_log(LOG_WARNING, "Don't know what to do with  frame type '%d'\n", frame->frametype);
 		return 0;
 	}
-	if (!(frame->subclass.codec &
-		(AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW | AST_FORMAT_G729A)) && 
+	if (!(frame->subclass.format.id == AST_FORMAT_G723_1 ||
+		frame->subclass.format.id == AST_FORMAT_SLINEAR ||
+		frame->subclass.format.id == AST_FORMAT_ULAW ||
+		frame->subclass.format.id == AST_FORMAT_G729A) &&
 	    p->mode != MODE_FXS) {
-		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(frame->subclass.codec));
+		ast_log(LOG_WARNING, "Cannot handle frames in %s format\n", ast_getformatname(&frame->subclass.format));
 		return -1;
 	}
 #if 0
@@ -680,8 +680,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 		return 0;
 	}
 #endif	
-	if (frame->subclass.codec == AST_FORMAT_G729A) {
-		if (p->lastformat != AST_FORMAT_G729A) {
+	if (frame->subclass.format.id == AST_FORMAT_G729A) {
+		if (p->lastformat.id != AST_FORMAT_G729A) {
 			ioctl(p->fd, PHONE_PLAY_STOP);
 			ioctl(p->fd, PHONE_REC_STOP);
 			if (ioctl(p->fd, PHONE_PLAY_CODEC, G729)) {
@@ -692,8 +692,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 				ast_log(LOG_WARNING, "Unable to set G729 mode\n");
 				return -1;
 			}
-			p->lastformat = AST_FORMAT_G729A;
-			p->lastinput = AST_FORMAT_G729A;
+			ast_format_set(&p->lastformat, AST_FORMAT_G729A, 0);
+			ast_format_set(&p->lastinput, AST_FORMAT_G729A, 0);
 			/* Reset output buffer */
 			p->obuflen = 0;
 			codecset = 1;
@@ -703,8 +703,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 			return -1;
 		}
 		maxfr = 80;
-        } else if (frame->subclass.codec == AST_FORMAT_G723_1) {
-		if (p->lastformat != AST_FORMAT_G723_1) {
+        } else if (frame->subclass.format.id == AST_FORMAT_G723_1) {
+		if (p->lastformat.id != AST_FORMAT_G723_1) {
 			ioctl(p->fd, PHONE_PLAY_STOP);
 			ioctl(p->fd, PHONE_REC_STOP);
 			if (ioctl(p->fd, PHONE_PLAY_CODEC, G723_63)) {
@@ -715,8 +715,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 				ast_log(LOG_WARNING, "Unable to set G723.1 mode\n");
 				return -1;
 			}
-			p->lastformat = AST_FORMAT_G723_1;
-			p->lastinput = AST_FORMAT_G723_1;
+			ast_format_set(&p->lastformat, AST_FORMAT_G723_1, 0);
+			ast_format_set(&p->lastinput, AST_FORMAT_G723_1, 0);
 			/* Reset output buffer */
 			p->obuflen = 0;
 			codecset = 1;
@@ -726,8 +726,8 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 			return -1;
 		}
 		maxfr = 24;
-	} else if (frame->subclass.codec == AST_FORMAT_SLINEAR) {
-		if (p->lastformat != AST_FORMAT_SLINEAR) {
+	} else if (frame->subclass.format.id == AST_FORMAT_SLINEAR) {
+		if (p->lastformat.id != AST_FORMAT_SLINEAR) {
 			ioctl(p->fd, PHONE_PLAY_STOP);
 			ioctl(p->fd, PHONE_REC_STOP);
 			if (ioctl(p->fd, PHONE_PLAY_CODEC, LINEAR16)) {
@@ -738,15 +738,15 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 				ast_log(LOG_WARNING, "Unable to set 16-bit linear mode\n");
 				return -1;
 			}
-			p->lastformat = AST_FORMAT_SLINEAR;
-			p->lastinput = AST_FORMAT_SLINEAR;
+			ast_format_set(&p->lastformat, AST_FORMAT_SLINEAR, 0);
+			ast_format_set(&p->lastinput, AST_FORMAT_SLINEAR, 0);
 			codecset = 1;
 			/* Reset output buffer */
 			p->obuflen = 0;
 		}
 		maxfr = 480;
-	} else if (frame->subclass.codec == AST_FORMAT_ULAW) {
-		if (p->lastformat != AST_FORMAT_ULAW) {
+	} else if (frame->subclass.format.id == AST_FORMAT_ULAW) {
+		if (p->lastformat.id != AST_FORMAT_ULAW) {
 			ioctl(p->fd, PHONE_PLAY_STOP);
 			ioctl(p->fd, PHONE_REC_STOP);
 			if (ioctl(p->fd, PHONE_PLAY_CODEC, ULAW)) {
@@ -757,29 +757,29 @@ static int phone_write(struct ast_channel *ast, struct ast_frame *frame)
 				ast_log(LOG_WARNING, "Unable to set uLaw mode\n");
 				return -1;
 			}
-			p->lastformat = AST_FORMAT_ULAW;
-			p->lastinput = AST_FORMAT_ULAW;
+			ast_format_set(&p->lastformat, AST_FORMAT_ULAW, 0);
+			ast_format_set(&p->lastinput, AST_FORMAT_ULAW, 0);
 			codecset = 1;
 			/* Reset output buffer */
 			p->obuflen = 0;
 		}
 		maxfr = 240;
 	} else {
-		if (p->lastformat != frame->subclass.codec) {
+		if (ast_format_cmp(&p->lastformat, &frame->subclass.format) != AST_FORMAT_CMP_EQUAL) {
 			ioctl(p->fd, PHONE_PLAY_STOP);
 			ioctl(p->fd, PHONE_REC_STOP);
-			if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.codec)) {
+			if (ioctl(p->fd, PHONE_PLAY_CODEC, (int) frame->subclass.format.id)) {
 				ast_log(LOG_WARNING, "Unable to set %s mode\n",
-					ast_getformatname(frame->subclass.codec));
+					ast_getformatname(&frame->subclass.format));
 				return -1;
 			}
-			if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.codec)) {
+			if (ioctl(p->fd, PHONE_REC_CODEC, (int) frame->subclass.format.id)) {
 				ast_log(LOG_WARNING, "Unable to set %s mode\n",
-					ast_getformatname(frame->subclass.codec));
+					ast_getformatname(&frame->subclass.format));
 				return -1;
 			}
-			p->lastformat = frame->subclass.codec;
-			p->lastinput = frame->subclass.codec;
+			ast_format_copy(&p->lastformat, &frame->subclass.format);
+			ast_format_copy(&p->lastinput, &frame->subclass.format);
 			codecset = 1;
 			/* Reset output buffer */
 			p->obuflen = 0;
@@ -850,6 +850,7 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
 {
 	struct ast_channel *tmp;
 	struct phone_codec_data queried_codec;
+	struct ast_format tmpfmt;
 	tmp = ast_channel_alloc(1, state, i->cid_num, i->cid_name, "", i->ext, i->context, linkedid, 0, "Phone/%s", i->dev + 5);
 	if (tmp) {
 		tmp->tech = cur_tech;
@@ -857,22 +858,18 @@ static struct ast_channel *phone_new(struct phone_pvt *i, int state, char *cntx,
 		/* XXX Switching formats silently causes kernel panics XXX */
 		if (i->mode == MODE_FXS &&
 		    ioctl(i->fd, PHONE_QUERY_CODEC, &queried_codec) == 0) {
-			if (queried_codec.type == LINEAR16)
-				tmp->nativeformats =
-				tmp->rawreadformat =
-				tmp->rawwriteformat =
-				AST_FORMAT_SLINEAR;
-			else {
-				tmp->nativeformats =
-				tmp->rawreadformat =
-				tmp->rawwriteformat =
-				prefformat & ~AST_FORMAT_SLINEAR;
+			if (queried_codec.type == LINEAR16) {
+				ast_format_cap_add(tmp->nativeformats, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+				ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+				ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+			} else {
+				ast_format_cap_remove(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 			}
-		}
-		else {
-			tmp->nativeformats = prefformat;
-			tmp->rawreadformat = prefformat;
-			tmp->rawwriteformat = prefformat;
+		} else {
+			ast_format_cap_copy(tmp->nativeformats, prefcap);
+			ast_best_codec(tmp->nativeformats, &tmpfmt);
+			ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+			ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
 		}
 		/* no need to call ast_setstate: the channel_alloc already did its job */
 		if (state == AST_STATE_RING)
@@ -981,7 +978,7 @@ static void phone_check_exception(struct phone_pvt *i)
 				ioctl(i->fd, PHONE_PLAY_STOP);
 				ioctl(i->fd, PHONE_PLAY_CODEC, ULAW);
 				ioctl(i->fd, PHONE_PLAY_START);
-				i->lastformat = -1;
+				ast_format_clear(&i->lastformat);
 			} else if (i->mode == MODE_SIGMA) {
 				ast_module_ref(ast_module_info->self);
 				/* Reset the extension */
@@ -1002,7 +999,7 @@ static void phone_check_exception(struct phone_pvt *i)
 			ioctl(i->fd, PHONE_PLAY_STOP);
 			ioctl(i->fd, PHONE_REC_STOP);
 			i->dialtone = 0;
-			i->lastformat = -1;
+			ast_format_clear(&i->lastformat);
 		}
 	}
 	if (phonee.bits.pstn_ring) {
@@ -1214,8 +1211,8 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
 		flags = fcntl(tmp->fd, F_GETFL);
 		fcntl(tmp->fd, F_SETFL, flags | O_NONBLOCK);
 		tmp->owner = NULL;
-		tmp->lastformat = -1;
-		tmp->lastinput = -1;
+		ast_format_clear(&tmp->lastformat);
+		ast_format_clear(&tmp->lastinput);
 		tmp->ministate = 0;
 		memset(tmp->ext, 0, sizeof(tmp->ext));
 		ast_copy_string(tmp->language, language, sizeof(tmp->language));
@@ -1235,9 +1232,8 @@ static struct phone_pvt *mkif(const char *iface, int mode, int txgain, int rxgai
 	return tmp;
 }
 
-static struct ast_channel *phone_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *phone_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat;
 	struct phone_pvt *p;
 	struct ast_channel *tmp = NULL;
 	char *name = data;
@@ -1249,9 +1245,8 @@ static struct ast_channel *phone_request(const char *type, format_t format, cons
 	}
 	p = iflist;
 	while(p) {
-		if (p->mode == MODE_FXS ||
-		    format & (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW)) {
-		    size_t length = strlen(p->dev + 5);
+		if (p->mode == MODE_FXS || (ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
+			size_t length = strlen(p->dev + 5);
     		if (strncmp(name, p->dev + 5, length) == 0 &&
     		    !isalnum(name[length])) {
     		    if (!p->owner) {
@@ -1266,11 +1261,9 @@ static struct ast_channel *phone_request(const char *type, format_t format, cons
 	ast_mutex_unlock(&iflock);
 	restart_monitor();
 	if (tmp == NULL) {
-		oldformat = format;
-		format &= (AST_FORMAT_G729A | AST_FORMAT_G723_1 | AST_FORMAT_SLINEAR | AST_FORMAT_ULAW);
-		if (!format) {
+		if (!(ast_format_cap_has_joint(cap, phone_tech.capabilities))) {
 			char buf[256];
-			ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), oldformat));
+			ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
 			return NULL;
 		}
 	}
@@ -1352,7 +1345,10 @@ static int __unload_module(void)
 		ast_log(LOG_WARNING, "Unable to lock the monitor\n");
 		return -1;
 	}
-		
+
+	phone_tech.capabilities = ast_format_cap_destroy(phone_tech.capabilities);
+	phone_tech_fxs.capabilities = ast_format_cap_destroy(phone_tech_fxs.capabilities);
+	prefcap = ast_format_cap_destroy(prefcap);
 	return 0;
 }
 
@@ -1369,6 +1365,23 @@ static int load_module(void)
 	int mode = MODE_IMMEDIATE;
 	int txgain = DEFAULT_GAIN, rxgain = DEFAULT_GAIN; /* default gain 1.0 */
 	struct ast_flags config_flags = { 0 };
+	struct ast_format tmpfmt;
+
+	if (!(phone_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
+	ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(phone_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
+
+	if (!(prefcap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_copy(prefcap, phone_tech.capabilities);
+	if (!(phone_tech_fxs.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
 
 	if ((cfg = ast_config_load(config, config_flags)) == CONFIG_STATUS_FILEINVALID) {
 		ast_log(LOG_ERROR, "Config file %s is in an invalid format.  Aborting.\n", config);
@@ -1416,7 +1429,7 @@ static int load_module(void)
 				mode = MODE_IMMEDIATE;
 			else if (!strncasecmp(v->value, "fxs", 3)) {
 				mode = MODE_FXS;
-				prefformat = 0x01ff0000; /* All non-voice */
+				ast_format_cap_remove_bytype(prefcap, AST_FORMAT_TYPE_AUDIO); /* All non-voice */
 			}
 			else if (!strncasecmp(v->value, "fx", 2))
 				mode = MODE_FXO;
@@ -1425,16 +1438,20 @@ static int load_module(void)
 		} else if (!strcasecmp(v->name, "context")) {
 			ast_copy_string(context, v->value, sizeof(context));
 		} else if (!strcasecmp(v->name, "format")) {
+			struct ast_format tmpfmt;
 			if (!strcasecmp(v->value, "g729")) {
-				prefformat = AST_FORMAT_G729A;
-                        } else if (!strcasecmp(v->value, "g723.1")) {
-				prefformat = AST_FORMAT_G723_1;
+				ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G729A, 0));
+			} else if (!strcasecmp(v->value, "g723.1")) {
+				ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_G723_1, 0));
 			} else if (!strcasecmp(v->value, "slinear")) {
-				if (mode == MODE_FXS)
-				    prefformat |= AST_FORMAT_SLINEAR;
-				else prefformat = AST_FORMAT_SLINEAR;
+				ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
+				if (mode == MODE_FXS) {
+					ast_format_cap_add(prefcap, &tmpfmt);
+				} else {
+					ast_format_cap_set(prefcap, &tmpfmt);
+				}
 			} else if (!strcasecmp(v->value, "ulaw")) {
-				prefformat = AST_FORMAT_ULAW;
+				ast_format_cap_set(prefcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
 			} else
 				ast_log(LOG_WARNING, "Unknown format '%s'\n", v->value);
 		} else if (!strcasecmp(v->name, "echocancel")) {
@@ -1458,7 +1475,7 @@ static int load_module(void)
 	ast_mutex_unlock(&iflock);
 
 	if (mode == MODE_FXS) {
-		phone_tech_fxs.capabilities = prefformat;
+		ast_format_cap_copy(phone_tech_fxs.capabilities, prefcap);
 		cur_tech = &phone_tech_fxs;
 	} else
 		cur_tech = (struct ast_channel_tech *) &phone_tech;
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index d5ee01345e8dda973597e86281ff8debcf049c90..e80f387cc99e5a7f399ba6ffbf940948a16ff138 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -1199,7 +1199,7 @@ static struct ast_config *notify_types = NULL;    /*!< The list of manual NOTIFY
 	in coming releases. */
 
 /*--- PBX interface functions */
-static struct ast_channel *sip_request_call(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int sip_devicestate(void *data);
 static int sip_sendtext(struct ast_channel *ast, const char *text);
 static int sip_call(struct ast_channel *ast, char *dest, int timeout);
@@ -1291,7 +1291,7 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
 static int process_sdp_a_video(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newvideortp, int *last_rtpmap_codec);
 static int process_sdp_a_text(const char *a, struct sip_pvt *p, struct ast_rtp_codecs *newtextrtp, char *red_fmtp, int *red_num_gen, int *red_data_pt, int *last_rtpmap_codec);
 static int process_sdp_a_image(const char *a, struct sip_pvt *p);
-static void add_codec_to_sdp(const struct sip_pvt *p, format_t codec,
+static void add_codec_to_sdp(const struct sip_pvt *p, struct ast_format *codec,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size);
 static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
@@ -1565,7 +1565,7 @@ static enum st_mode st_get_mode(struct sip_pvt *);
 static struct sip_st_dlg* sip_st_alloc(struct sip_pvt *const p);
 
 /*------- RTP Glue functions -------- */
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active);
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active);
 
 /*!--- SIP MWI Subscription support */
 static int sip_subscribe_mwi(const char *value, int lineno);
@@ -1575,10 +1575,9 @@ static int sip_subscribe_mwi_do(const void *data);
 static int __sip_subscribe_mwi_do(struct sip_subscription_mwi *mwi);
 
 /*! \brief Definition of this channel for PBX channel registration */
-const struct ast_channel_tech sip_tech = {
+struct ast_channel_tech sip_tech = {
 	.type = "SIP",
 	.description = "Session Initiation Protocol (SIP)",
-	.capabilities = AST_FORMAT_AUDIO_MASK,	/* all audio formats */
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = sip_request_call,			/* called with chan unlocked */
 	.devicestate = sip_devicestate,			/* called with chan unlocked (not chan-specific) */
@@ -4038,10 +4037,10 @@ static int sip_setoption(struct ast_channel *chan, int option, void *data, int d
 
 	switch (option) {
 	case AST_OPTION_FORMAT_READ:
-		res = ast_rtp_instance_set_read_format(p->rtp, *(int *) data);
+		res = ast_rtp_instance_set_read_format(p->rtp, (struct ast_format *) data);
 		break;
 	case AST_OPTION_FORMAT_WRITE:
-		res = ast_rtp_instance_set_write_format(p->rtp, *(int *) data);
+		res = ast_rtp_instance_set_write_format(p->rtp, (struct ast_format *) data);
 		break;
 	case AST_OPTION_MAKE_COMPATIBLE:
 		res = ast_rtp_instance_make_compatible(chan, p->rtp, (struct ast_channel *) data);
@@ -4385,6 +4384,8 @@ static void sip_destroy_peer(struct sip_peer *peer)
 	ast_cc_config_params_destroy(peer->cc_params);
 
 	ast_string_field_free_memory(peer);
+
+	peer->caps = ast_format_cap_destroy(peer->caps);
 }
 
 /*! \brief Update peer data in database (if used) */
@@ -4826,7 +4827,7 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
 	}
 
 	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT_ALWAYS) ||
-			(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (dialog->capability & AST_FORMAT_VIDEO_MASK))) {
+			(ast_test_flag(&dialog->flags[1], SIP_PAGE2_VIDEOSUPPORT) && (ast_format_cap_has_type(dialog->caps, AST_FORMAT_TYPE_VIDEO)))) {
 		if (!(dialog->vrtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
 			return -1;
 		}
@@ -4887,7 +4888,7 @@ static int create_addr_from_peer(struct sip_pvt *dialog, struct sip_peer *peer)
 	ast_copy_flags(&dialog->flags[0], &peer->flags[0], SIP_FLAGS_TO_COPY);
 	ast_copy_flags(&dialog->flags[1], &peer->flags[1], SIP_PAGE2_FLAGS_TO_COPY);
 	ast_copy_flags(&dialog->flags[2], &peer->flags[2], SIP_PAGE3_FLAGS_TO_COPY);
-	dialog->capability = peer->capability;
+	ast_format_cap_append(dialog->caps, peer->caps);
 	dialog->prefs = peer->prefs;
 	if (ast_test_flag(&dialog->flags[1], SIP_PAGE2_T38SUPPORT)) {
 		/* t38pt_udptl was enabled in the peer and not in [general] */
@@ -5253,11 +5254,11 @@ static int sip_call(struct ast_channel *ast, char *dest, int timeout)
 		return res;
 	}
 	p->callingpres = ast_party_id_presentation(&ast->caller.id);
-	p->jointcapability = ast_rtp_instance_available_formats(p->rtp, p->capability, p->prefcodec);
+	ast_rtp_instance_available_formats(p->rtp, p->caps, p->prefcaps, p->jointcaps);
 	p->jointnoncodeccapability = p->noncodeccapability;
 
 	/* If there are no audio formats left to offer, punt */
-	if (!(p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
+	if (!(ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO))) {
 		ast_log(LOG_WARNING, "No audio format found to offer. Cancelling call to %s\n", p->username);
 		res = -1;
 	} else {
@@ -5463,6 +5464,11 @@ void __sip_destroy(struct sip_pvt *p, int lockowner, int lockdialoglist)
 		ao2_ref(p->socket.tcptls_session, -1);
 		p->socket.tcptls_session = NULL;
 	}
+	p->caps = ast_format_cap_destroy(p->caps);
+	p->jointcaps = ast_format_cap_destroy(p->jointcaps);
+	p->peercaps = ast_format_cap_destroy(p->peercaps);
+	p->redircaps = ast_format_cap_destroy(p->redircaps);
+	p->prefcaps = ast_format_cap_destroy(p->prefcaps);
 }
 
 /*! \brief  update_call_counter: Handle call_limit for SIP devices
@@ -6025,9 +6031,11 @@ static int sip_hangup(struct ast_channel *ast)
 /*! \brief Try setting codec suggested by the SIP_CODEC channel variable */
 static void try_suggested_sip_codec(struct sip_pvt *p)
 {
-	format_t fmt;
+	struct ast_format fmt;
 	const char *codec;
 
+	ast_format_clear(&fmt);
+
 	if (p->outgoing_call) {
 		codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_OUTBOUND");
 	} else if (!(codec = pbx_builtin_getvar_helper(p->owner, "SIP_CODEC_INBOUND"))) {
@@ -6037,12 +6045,12 @@ static void try_suggested_sip_codec(struct sip_pvt *p)
 	if (!codec) 
 		return;
 
-	fmt = ast_getformatbyname(codec);
-	if (fmt) {
+	ast_getformatbyname(codec, &fmt);
+	if (fmt.id) {
 		ast_log(LOG_NOTICE, "Changing codec to '%s' for this call because of ${SIP_CODEC} variable\n", codec);
-		if (p->jointcapability & fmt) {
-			p->jointcapability &= fmt;
-			p->capability &= fmt;
+		if (ast_format_cap_iscompatible(p->jointcaps, &fmt)) {
+			ast_format_cap_set(p->jointcaps, &fmt);
+			ast_format_cap_set(p->caps, &fmt);
 		} else
 			ast_log(LOG_NOTICE, "Ignoring ${SIP_CODEC} variable because it is not shared by both ends.\n");
 	} else
@@ -6079,13 +6087,13 @@ static int sip_write(struct ast_channel *ast, struct ast_frame *frame)
 
 	switch (frame->frametype) {
 	case AST_FRAME_VOICE:
-		if (!(frame->subclass.codec & ast->nativeformats)) {
-			char s1[512], s2[512], s3[512];
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
+			char s1[512];
 			ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s read/write = %s/%s\n",
-				ast_getformatname(frame->subclass.codec),
-				ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats & AST_FORMAT_AUDIO_MASK),
-				ast_getformatname_multiple(s2, sizeof(s2), ast->readformat),
-				ast_getformatname_multiple(s3, sizeof(s3), ast->writeformat));
+				ast_getformatname(&frame->subclass.format),
+				ast_getformatname_multiple(s1, sizeof(s1), ast->nativeformats),
+				ast_getformatname(&ast->readformat),
+				ast_getformatname(&ast->writeformat));
 			return 0;
 		}
 		if (p) {
@@ -6538,11 +6546,9 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
 {
 	struct ast_channel *tmp;
 	struct ast_variable *v = NULL;
-	format_t fmt;
-	format_t what;
-	format_t video;
-	format_t text;
-	format_t needvideo = 0;
+	struct ast_format fmt;
+	struct ast_format_cap *what = NULL; /* SHALLOW COPY DO NOT DESTROY! */
+	int needvideo = 0;
 	int needtext = 0;
 	char buf[SIPBUFSIZE];
 	char *decoded_exten;
@@ -6575,51 +6581,47 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
 
 	/* Select our native format based on codec preference until we receive
 	   something from another device to the contrary. */
-	if (i->jointcapability) { 	/* The joint capabilities of us and peer */
-		what = i->jointcapability;
-		video = i->jointcapability & AST_FORMAT_VIDEO_MASK;
-		text = i->jointcapability & AST_FORMAT_TEXT_MASK;
-	} else if (i->capability) {		/* Our configured capability for this peer */
-		what = i->capability;
-		video = i->capability & AST_FORMAT_VIDEO_MASK;
-		text = i->capability & AST_FORMAT_TEXT_MASK;
+	if (!(ast_format_cap_is_empty(i->jointcaps))) {	/* The joint capabilities of us and peer */
+		what = i->jointcaps;
+	} else if (!(ast_format_cap_is_empty(i->caps))) {		/* Our configured capability for this peer */
+		what = i->caps;
 	} else {
-		what = sip_cfg.capability;	/* Global codec support */
-		video = sip_cfg.capability & AST_FORMAT_VIDEO_MASK;
-		text = sip_cfg.capability & AST_FORMAT_TEXT_MASK;
+		what = sip_cfg.caps;
 	}
 
-	/* Set the native formats for audio  and merge in video */
-	tmp->nativeformats = ast_codec_choose(&i->prefs, what, 1) | video | text;
+	/* Set the native formats */
+	ast_format_cap_copy(tmp->nativeformats, what);
+	/* choose and use only the best audio format for our native formats */
+	ast_codec_choose(&i->prefs, tmp->nativeformats, 1, &fmt); /* get the best audio format */
+	ast_format_cap_remove_bytype(tmp->nativeformats, AST_FORMAT_TYPE_AUDIO); /* remove only the other audio formats */
+	ast_format_cap_add(tmp->nativeformats, &fmt); /* add our best choice back */
+
 	ast_debug(3, "*** Our native formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmp->nativeformats));
-	ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcapability));
-	ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->capability));
-	ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, ast_codec_choose(&i->prefs, what, 1)));
-	if (i->prefcodec) {
-		ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcodec));
+	ast_debug(3, "*** Joint capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->jointcaps));
+	ast_debug(3, "*** Our capabilities are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->caps));
+	ast_debug(3, "*** AST_CODEC_CHOOSE formats are %s \n", ast_getformatname(&fmt));
+	if (!ast_format_cap_is_empty(i->prefcaps)) {
+		ast_debug(3, "*** Our preferred formats from the incoming channel are %s \n", ast_getformatname_multiple(buf, SIPBUFSIZE, i->prefcaps));
 	}
 
-	/* XXX Why are we choosing a codec from the native formats?? */
-	fmt = ast_best_codec(tmp->nativeformats);
-
 	/* If we have a prefcodec setting, we have an inbound channel that set a
 	   preferred format for this call. Otherwise, we check the jointcapability
 	   We also check for vrtp. If it's not there, we are not allowed do any video anyway.
 	 */
 	if (i->vrtp) {
 		if (ast_test_flag(&i->flags[1], SIP_PAGE2_VIDEOSUPPORT))
-			needvideo = AST_FORMAT_VIDEO_MASK;
-		else if (i->prefcodec)
-			needvideo = i->prefcodec & AST_FORMAT_VIDEO_MASK;	/* Outbound call */
+			needvideo = 1;
+		else if (!ast_format_cap_is_empty(i->prefcaps))
+			needvideo = ast_format_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_VIDEO);	/* Outbound call */
  		else
-			needvideo = i->jointcapability & AST_FORMAT_VIDEO_MASK;	/* Inbound call */
+			needvideo = ast_format_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_VIDEO);	/* Inbound call */
 	}
 
 	if (i->trtp) {
-		if (i->prefcodec)
-			needtext = i->prefcodec & AST_FORMAT_TEXT_MASK;	/* Outbound call */
+		if (!ast_format_cap_is_empty(i->prefcaps))
+			needtext = ast_format_cap_has_type(i->prefcaps, AST_FORMAT_TYPE_TEXT);	/* Outbound call */
  		else
-			needtext = i->jointcapability & AST_FORMAT_TEXT_MASK;	/* Inbound call */
+			needtext = ast_format_cap_has_type(i->jointcaps, AST_FORMAT_TYPE_TEXT);	/* Inbound call */
 	}
 
 	if (needvideo) {
@@ -6662,13 +6664,13 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
 	}
 	tmp->adsicpe = AST_ADSI_UNAVAILABLE;
 
-	tmp->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	ast_rtp_instance_set_write_format(i->rtp, fmt);
+	ast_format_copy(&tmp->writeformat, &fmt);
+	ast_format_copy(&tmp->rawwriteformat, &fmt);
+	ast_rtp_instance_set_write_format(i->rtp, &fmt);
 
-	tmp->readformat = fmt;
-	tmp->rawreadformat = fmt;
-	ast_rtp_instance_set_read_format(i->rtp, fmt);
+	ast_format_copy(&tmp->readformat, &fmt);
+	ast_format_copy(&tmp->rawreadformat, &fmt);
+	ast_rtp_instance_set_read_format(i->rtp, &fmt);
 
 	tmp->tech_pvt = dialog_ref(i, "sip_new: set chan->tech_pvt to i");
 
@@ -6976,17 +6978,18 @@ static struct ast_frame *sip_rtp_read(struct ast_channel *ast, struct sip_pvt *p
 		return f;
 	}
 
-	if (f && f->subclass.codec != (p->owner->nativeformats & AST_FORMAT_AUDIO_MASK)) {
-		if (!(f->subclass.codec & p->jointcapability)) {
+	if (f && !ast_format_cap_iscompatible(p->owner->nativeformats, &f->subclass.format)) {
+		if (!ast_format_cap_iscompatible(p->jointcaps, &f->subclass.format)) {
 			ast_debug(1, "Bogus frame of format '%s' received from '%s'!\n",
-				ast_getformatname(f->subclass.codec), p->owner->name);
+				ast_getformatname(&f->subclass.format), p->owner->name);
 			return &ast_null_frame;
 		}
 		ast_debug(1, "Oooh, format changed to %s\n",
-			ast_getformatname(f->subclass.codec));
-		p->owner->nativeformats = (p->owner->nativeformats & (AST_FORMAT_VIDEO_MASK | AST_FORMAT_TEXT_MASK)) | f->subclass.codec;
-		ast_set_read_format(p->owner, p->owner->readformat);
-		ast_set_write_format(p->owner, p->owner->writeformat);
+			ast_getformatname(&f->subclass.format));
+		ast_format_cap_remove_bytype(p->owner->nativeformats, AST_FORMAT_TYPE_AUDIO);
+		ast_format_cap_add(p->owner->nativeformats, &f->subclass.format);
+		ast_set_read_format(p->owner, &p->owner->readformat);
+		ast_set_write_format(p->owner, &p->owner->writeformat);
 	}
 
 	if (f && p->dsp) {
@@ -7149,6 +7152,22 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
 		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
 		return NULL;
 	}
+	p->caps = ast_format_cap_alloc_nolock();
+	p->jointcaps = ast_format_cap_alloc_nolock();
+	p->peercaps = ast_format_cap_alloc_nolock();
+	p->redircaps = ast_format_cap_alloc_nolock();
+	p->prefcaps = ast_format_cap_alloc_nolock();
+
+	if (!p->caps|| !p->jointcaps || !p->peercaps || !p->redircaps) {
+		p->caps = ast_format_cap_destroy(p->caps);
+		p->jointcaps = ast_format_cap_destroy(p->jointcaps);
+		p->peercaps = ast_format_cap_destroy(p->peercaps);
+		p->redircaps = ast_format_cap_destroy(p->redircaps);
+		p->prefcaps = ast_format_cap_destroy(p->prefcaps);
+		ao2_t_ref(p, -1, "Yuck, couldn't allocate cc_params struct. Get rid o' p");
+		return NULL;
+	}
+
 
 	/* If this dialog is created as a result of a request or response, lets store
 	 * some information about it in the dialog. */
@@ -7255,7 +7274,7 @@ struct sip_pvt *sip_alloc(ast_string_field callid, struct ast_sockaddr *addr,
 	/* Assign default music on hold class */
 	ast_string_field_set(p, mohinterpret, default_mohinterpret);
 	ast_string_field_set(p, mohsuggest, default_mohsuggest);
-	p->capability = sip_cfg.capability;
+	ast_format_cap_append(p->caps, sip_cfg.caps);
 	p->allowtransfer = sip_cfg.allowtransfer;
 	if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
 	    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
@@ -8262,6 +8281,8 @@ static int get_ip_and_port_from_sdp(struct sip_request *req, const enum media_ty
 */
 static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action)
 {
+	int res = 0;
+
 	/* Iterators for SDP parsing */
 	int start = req->sdp_start;
 	int next = start;
@@ -8284,18 +8305,21 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 	struct ast_sockaddr *vsa = NULL;	/*!< RTP video host IP */
 	struct ast_sockaddr *tsa = NULL;	/*!< RTP text host IP */
 	struct ast_sockaddr *isa = NULL;     /*!< UDPTL host ip */
- 	int portno = -1;		/*!< RTP Audio port number */
- 	int vportno = -1;		/*!< RTP Video port number */
+	int portno = -1;		/*!< RTP Audio port number */
+	int vportno = -1;		/*!< RTP Video port number */
 	int tportno = -1;		/*!< RTP Text port number */
 	int udptlportno = -1;		/*!< UDPTL Image port number */
 
 	/* Peer capability is the capability in the SDP, non codec is RFC2833 DTMF (101) */	
-	format_t peercapability = 0, vpeercapability = 0, tpeercapability = 0;
+	struct ast_format_cap *peercapability = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *vpeercapability = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *tpeercapability = ast_format_cap_alloc_nolock();
+
 	int peernoncodeccapability = 0, vpeernoncodeccapability = 0, tpeernoncodeccapability = 0;
 
 	struct ast_rtp_codecs newaudiortp, newvideortp, newtextrtp;
-	format_t newjointcapability;				/* Negotiated capability */
-	format_t newpeercapability;
+	struct ast_format_cap *newjointcapability = ast_format_cap_alloc_nolock(); /* Negotiated capability */
+	struct ast_format_cap *newpeercapability = ast_format_cap_alloc_nolock();
 	int newnoncodeccapability;
 
 	const char *codecs;
@@ -8318,12 +8342,18 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 
 	/* START UNKNOWN */
 	char buf[SIPBUFSIZE];
+	struct ast_format tmp_fmt;
 	/* END UNKNOWN */
 
 	/* Initial check */
 	if (!p->rtp) {
 		ast_log(LOG_ERROR, "Got SDP but have no RTP session allocated.\n");
-		return -1;
+		res = -1;
+		goto process_sdp_cleanup;
+	}
+	if (!peercapability || !vpeercapability || !tpeercapability || !newpeercapability || !newjointcapability) {
+		res = -1;
+		goto process_sdp_cleanup;
 	}
 
 	/* Make sure that the codec structures are all cleared out */
@@ -8353,7 +8383,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 	nextm = get_sdp_iterate(&next, req, "m");
 	if (ast_strlen_zero(nextm)) {
 		ast_log(LOG_WARNING, "Insufficient information for SDP (m= not found)\n");
- 		return -1;
+		res = -1;
+		goto process_sdp_cleanup;
  	}
 
 	/* Scan session level SDP parameters (lines before first media stream) */
@@ -8364,8 +8395,10 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 			/* If we end up receiving SDP that doesn't actually modify the session we don't want to treat this as a fatal
 			 * error. We just want to ignore the SDP and let the rest of the packet be handled as normal.
 			 */
-			if (!process_sdp_o(value, p))
-				return (p->session_modify == FALSE) ? 0 : -1;
+			if (!process_sdp_o(value, p)) {
+				res = (p->session_modify == FALSE) ? 0 : -1;
+				goto process_sdp_cleanup;
+			}
 			break;
 		case 'c':
 			if (process_sdp_c(value, &sessionsa)) {
@@ -8433,7 +8466,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
 				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
 					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP audio format %d\n", codec);
@@ -8461,7 +8495,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
 				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
 					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP video format %d\n", codec);
@@ -8482,7 +8517,8 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 			for (; !ast_strlen_zero(codecs); codecs = ast_skip_blanks(codecs + len)) {
 				if (sscanf(codecs, "%30u%n", &codec, &len) != 1) {
 					ast_log(LOG_WARNING, "Error in codec string '%s'\n", codecs);
-					return -1;
+					res = -1;
+					goto process_sdp_cleanup;
 				}
 				if (debug)
 					ast_verbose("Found RTP text format %d\n", codec);
@@ -8587,45 +8623,53 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 	/* Sanity checks */
 	if (!sa && !vsa && !tsa && !isa) {
 		ast_log(LOG_WARNING, "Insufficient information in SDP (c=)...\n");
-		return -1;
+		res = -1;
+		goto process_sdp_cleanup;
 	}
 
 	if (portno == -1 && vportno == -1 && udptlportno == -1  && tportno == -1) {
 		/* No acceptable offer found in SDP  - we have no ports */
 		/* Do not change RTP or VRTP if this is a re-invite */
 		ast_log(LOG_WARNING, "Failing due to no acceptable offer found\n");
-		return -2;
+		res = -2;
+		goto process_sdp_cleanup;
 	}
 
 	if (numberofmediastreams > 3) {
 		/* We have too many fax, audio and/or video and/or text media streams, fail this offer */
 		ast_log(LOG_WARNING, "Faling due to too many media streams\n");
-		return -3;
+		res = -3;
+		goto process_sdp_cleanup;
 	}
 
 	if (secure_audio && !(p->srtp && (ast_test_flag(p->srtp, SRTP_CRYPTO_OFFER_OK)))) {
 		ast_log(LOG_WARNING, "Can't provide secure audio requested in SDP offer\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (!secure_audio && p->srtp) {
 		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (secure_video && !(p->vsrtp && (ast_test_flag(p->vsrtp, SRTP_CRYPTO_OFFER_OK)))) {
 		ast_log(LOG_WARNING, "Can't provide secure video requested in SDP offer\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (!p->novideo && !secure_video && p->vsrtp) {
 		ast_log(LOG_WARNING, "We are requesting SRTP, but they responded without it!\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (!(secure_audio || secure_video) && ast_test_flag(&p->flags[1], SIP_PAGE2_USE_SRTP)) {
 		ast_log(LOG_WARNING, "Matched device setup to use SRTP, but request was not!\n");
-		return -4;
+		res = -4;
+		goto process_sdp_cleanup;
 	}
 
 	if (udptlportno == -1) {
@@ -8633,12 +8677,22 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 	}
 
 	/* Now gather all of the codecs that we are asked for: */
-	ast_rtp_codecs_payload_formats(&newaudiortp, &peercapability, &peernoncodeccapability);
-	ast_rtp_codecs_payload_formats(&newvideortp, &vpeercapability, &vpeernoncodeccapability);
-	ast_rtp_codecs_payload_formats(&newtextrtp, &tpeercapability, &tpeernoncodeccapability);
+	ast_rtp_codecs_payload_formats(&newaudiortp, peercapability, &peernoncodeccapability);
+	ast_rtp_codecs_payload_formats(&newvideortp, vpeercapability, &vpeernoncodeccapability);
+	ast_rtp_codecs_payload_formats(&newtextrtp, tpeercapability, &tpeernoncodeccapability);
+
+	ast_format_cap_append(newpeercapability, peercapability);
+	ast_format_cap_append(newpeercapability, vpeercapability);
+	ast_format_cap_append(newpeercapability, tpeercapability);
+
+	ast_format_cap_joint_copy(p->caps, newpeercapability, newjointcapability);
+	if (ast_format_cap_is_empty(newjointcapability) && (portno != -1)) {
+		ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
+		/* Do NOT Change current setting */
+		res = -1;
+		goto process_sdp_cleanup;
+	}
 
-	newjointcapability = p->capability & (peercapability | vpeercapability | tpeercapability);
-	newpeercapability = (peercapability | vpeercapability | tpeercapability);
 	newnoncodeccapability = p->noncodeccapability & peernoncodeccapability;
 
 	if (debug) {
@@ -8646,7 +8700,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 		char s1[SIPBUFSIZE], s2[SIPBUFSIZE], s3[SIPBUFSIZE], s4[SIPBUFSIZE], s5[SIPBUFSIZE];
 
 		ast_verbose("Capabilities: us - %s, peer - audio=%s/video=%s/text=%s, combined - %s\n",
-			    ast_getformatname_multiple(s1, SIPBUFSIZE, p->capability),
+			    ast_getformatname_multiple(s1, SIPBUFSIZE, p->caps),
 			    ast_getformatname_multiple(s2, SIPBUFSIZE, peercapability),
 			    ast_getformatname_multiple(s3, SIPBUFSIZE, vpeercapability),
 			    ast_getformatname_multiple(s4, SIPBUFSIZE, tpeercapability),
@@ -8658,14 +8712,9 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 		struct ast_str *s3 = ast_str_alloca(SIPBUFSIZE);
 
 		ast_verbose("Non-codec capabilities (dtmf): us - %s, peer - %s, combined - %s\n",
-			    ast_rtp_lookup_mime_multiple2(s1, p->noncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple2(s2, peernoncodeccapability, 0, 0),
-			    ast_rtp_lookup_mime_multiple2(s3, newnoncodeccapability, 0, 0));
-	}
-	if (!newjointcapability && (portno != -1)) {
-		ast_log(LOG_NOTICE, "No compatible codecs, not accepting this offer!\n");
-		/* Do NOT Change current setting */
-		return -1;
+			    ast_rtp_lookup_mime_multiple2(s1, NULL, p->noncodeccapability, 0, 0),
+			    ast_rtp_lookup_mime_multiple2(s2, NULL, peernoncodeccapability, 0, 0),
+			    ast_rtp_lookup_mime_multiple2(s3, NULL, newnoncodeccapability, 0, 0));
 	}
 
 	/* Setup audio address and port */
@@ -8679,12 +8728,13 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 			}
 			/* We are now ready to change the sip session and p->rtp and p->vrtp with the offered codecs, since
 			   they are acceptable */
-			p->jointcapability = newjointcapability;                /* Our joint codec profile for this call */
-			p->peercapability = newpeercapability;                  /* The other sides capability in latest offer */
+			ast_format_cap_copy(p->jointcaps, newjointcapability);                /* Our joint codec profile for this call */
+			ast_format_cap_copy(p->peercaps, newpeercapability);                  /* The other sides capability in latest offer */
 			p->jointnoncodeccapability = newnoncodeccapability;     /* DTMF capabilities */
 
 			if (ast_test_flag(&p->flags[1], SIP_PAGE2_PREFERRED_CODEC)) { /* respond with single most preferred joint codec, limiting the other side's choice */
-				p->jointcapability = ast_codec_choose(&p->prefs, p->jointcapability, 1);
+				ast_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
+				ast_format_cap_set(p->jointcaps, &tmp_fmt);
 			}
 
 			ast_rtp_codecs_payloads_copy(&newaudiortp, ast_rtp_instance_get_codecs(p->rtp), p->rtp);
@@ -8737,7 +8787,7 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 				ast_verbose("Peer T.140 RTP is at port %s\n",
 					    ast_sockaddr_stringify(tsa));
 			}
-			if ((p->jointcapability & AST_FORMAT_T140RED)) {
+			if (ast_format_cap_iscompatible(p->jointcaps, ast_format_set(&tmp_fmt, AST_FORMAT_T140RED, 0))) {
 				p->red = 1;
 				ast_rtp_red_init(p->trtp, 300, red_data_pt, 2);
 			} else {
@@ -8807,27 +8857,36 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 
 	if ((portno == -1) && (p->t38.state != T38_DISABLED)) {
 		ast_debug(3, "Have T.38 but no audio, accepting offer anyway\n");
-		return 0;
-        }
+		res = 0;
+		goto process_sdp_cleanup;
+	}
 
 	/* Ok, we're going with this offer */
-	ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcapability));
+	ast_debug(2, "We're settling with these formats: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, p->jointcaps));
 
-	if (!p->owner) 	/* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
-		return 0;
+	if (!p->owner) { /* There's no open channel owning us so we can return here. For a re-invite or so, we proceed */
+		res = 0;
+		goto process_sdp_cleanup;
+	}
 
 	ast_debug(4, "We have an owner, now see if we need to change this call\n");
 
-	if (!(p->owner->nativeformats & p->jointcapability) && (p->jointcapability & AST_FORMAT_AUDIO_MASK)) {
+	if (!(ast_format_cap_has_joint(p->owner->nativeformats, p->jointcaps)) && ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_AUDIO)) {
 		if (debug) {
 			char s1[SIPBUFSIZE], s2[SIPBUFSIZE];
 			ast_debug(1, "Oooh, we need to change our audio formats since our peer supports only %s and not %s\n",
-				ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcapability),
+				ast_getformatname_multiple(s1, SIPBUFSIZE, p->jointcaps),
 				ast_getformatname_multiple(s2, SIPBUFSIZE, p->owner->nativeformats));
 		}
-		p->owner->nativeformats = ast_codec_choose(&p->prefs, p->jointcapability, 1) | (p->capability & vpeercapability) | (p->capability & tpeercapability);
-		ast_set_read_format(p->owner, p->owner->readformat);
-		ast_set_write_format(p->owner, p->owner->writeformat);
+
+		ast_codec_choose(&p->prefs, p->jointcaps, 1, &tmp_fmt);
+
+		ast_format_cap_set(p->owner->nativeformats, &tmp_fmt);
+		ast_format_cap_joint_copy(p->caps, vpeercapability, p->owner->nativeformats);
+		ast_format_cap_joint_copy(p->caps, tpeercapability, p->owner->nativeformats);
+
+		ast_set_read_format(p->owner, &p->owner->readformat);
+		ast_set_write_format(p->owner, &p->owner->writeformat);
 	}
 	
 	if (ast_test_flag(&p->flags[1], SIP_PAGE2_CALL_ONHOLD) && (!ast_sockaddr_isnull(sa) || !ast_sockaddr_isnull(vsa) || !ast_sockaddr_isnull(tsa) || !ast_sockaddr_isnull(isa)) && (!sendonly || sendonly == -1)) {
@@ -8846,8 +8905,14 @@ static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action
 		ast_queue_frame(p->owner, &ast_null_frame);
 		change_hold_state(p, req, TRUE, sendonly);
 	}
-	
-	return 0;
+
+process_sdp_cleanup:
+	ast_format_cap_destroy(peercapability);
+	ast_format_cap_destroy(vpeercapability);
+	ast_format_cap_destroy(tpeercapability);
+	ast_format_cap_destroy(newjointcapability);
+	ast_format_cap_destroy(newpeercapability);
+	return res;
 }
 
 static int process_sdp_o(const char *o, struct sip_pvt *p)
@@ -9001,10 +9066,10 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
 			int codec_n;
 			for (codec_n = 0; codec_n < AST_RTP_MAX_PT; codec_n++) {
 				struct ast_rtp_payload_type format = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(p->rtp), codec_n);
-				if (!format.asterisk_format || !format.code)	/* non-codec or not found */
+				if (!format.asterisk_format)	/* non-codec or not found */
 					continue;
-				ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(format.code), framing);
-				ast_codec_pref_setsize(pref, format.code, framing);
+				ast_debug(1, "Setting framing for %s to %ld\n", ast_getformatname(&format.format), framing);
+				ast_codec_pref_setsize(pref, &format.format, framing);
 			}
 			ast_rtp_codecs_packetization_set(ast_rtp_instance_get_codecs(p->rtp), p->rtp, pref);
 		}
@@ -9032,10 +9097,10 @@ static int process_sdp_a_audio(const char *a, struct sip_pvt *p, struct ast_rtp_
 		struct ast_rtp_payload_type payload;
 
 		payload = ast_rtp_codecs_payload_lookup(newaudiortp, codec);
-		if (payload.code && payload.asterisk_format) {
+		if (payload.format.id && payload.asterisk_format) {
 			unsigned int bit_rate;
 
-			switch (payload.code) {
+			switch ((int) payload.format.id) {
 			case AST_FORMAT_SIREN7:
 				if (sscanf(fmtp_string, "bitrate=%30u", &bit_rate) == 1) {
 					if (bit_rate != 32000) {
@@ -10373,31 +10438,34 @@ static int add_vidupdate(struct sip_request *req)
 }
 
 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_codec_to_sdp(const struct sip_pvt *p, format_t codec,
-			     struct ast_str **m_buf, struct ast_str **a_buf,
-			     int debug, int *min_packet_size)
+static void add_codec_to_sdp(const struct sip_pvt *p,
+	struct ast_format *format,
+	struct ast_str **m_buf,
+	struct ast_str **a_buf,
+	int debug,
+	int *min_packet_size)
 {
 	int rtp_code;
 	struct ast_format_list fmt;
 
 
 	if (debug)
-		ast_verbose("Adding codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, codec)) == -1)
+		ast_verbose("Adding codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 1, format, 0)) == -1)
 		return;
 
 	if (p->rtp) {
 		struct ast_codec_pref *pref = &ast_rtp_instance_get_codecs(p->rtp)->pref;
-		fmt = ast_codec_pref_getsize(pref, codec);
+		fmt = ast_codec_pref_getsize(pref, format);
 	} else /* I don't see how you couldn't have p->rtp, but good to check for and error out if not there like earlier code */
 		return;
 	ast_str_append(m_buf, 0, " %d", rtp_code);
-	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec,
-						   ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
+	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n",
+		rtp_code,
+		ast_rtp_lookup_mime_subtype2(1, format, 0, ast_test_flag(&p->flags[0], SIP_G726_NONSTANDARD) ? AST_RTP_OPT_G726_NONSTANDARD : 0),
+		ast_rtp_lookup_sample_rate2(1, format, 0));
 
-	switch (codec) {
+	switch ((int) format->id) {
 	case AST_FORMAT_G729A:
 		/* Indicate that we don't support VAD (G.729 annex B) */
 		ast_str_append(a_buf, 0, "a=fmtp:%d annexb=no\r\n", rtp_code);
@@ -10434,7 +10502,7 @@ static void add_codec_to_sdp(const struct sip_pvt *p, format_t codec,
 
 /*! \brief Add video codec offer to SDP offer/answer body in INVITE or 200 OK */
 /* This is different to the audio one now so we can add more caps later */
-static void add_vcodec_to_sdp(const struct sip_pvt *p, format_t codec,
+static void add_vcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -10444,20 +10512,20 @@ static void add_vcodec_to_sdp(const struct sip_pvt *p, format_t codec,
 		return;
 
 	if (debug)
-		ast_verbose("Adding video codec 0x%" PRIx64 " (%s) to SDP\n", codec, ast_getformatname(codec));
+		ast_verbose("Adding video codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
 
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, codec)) == -1)
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->vrtp), 1, format, 0)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec, 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
+		       ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
+		       ast_rtp_lookup_sample_rate2(1, format, 0));
 	/* Add fmtp code here */
 }
 
 /*! \brief Add text codec offer to SDP offer/answer body in INVITE or 200 OK */
-static void add_tcodec_to_sdp(const struct sip_pvt *p, int codec,
+static void add_tcodec_to_sdp(const struct sip_pvt *p, struct ast_format *format,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size)
 {
@@ -10467,19 +10535,20 @@ static void add_tcodec_to_sdp(const struct sip_pvt *p, int codec,
 		return;
 
 	if (debug)
-		ast_verbose("Adding text codec 0x%x (%s) to SDP\n", codec, ast_getformatname(codec));
+		ast_verbose("Adding text codec %d (%s) to SDP\n", format->id, ast_getformatname(format));
 
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, codec)) == -1)
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, format, 0)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(1, codec, 0),
-		       ast_rtp_lookup_sample_rate2(1, codec));
+		       ast_rtp_lookup_mime_subtype2(1, format, 0, 0),
+		       ast_rtp_lookup_sample_rate2(1, format, 0));
 	/* Add fmtp code here */
 
-	if (codec == AST_FORMAT_T140RED) {
-		int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, AST_FORMAT_T140);
+	if (format->id == AST_FORMAT_T140RED) {
+		struct ast_format tmp_fmt;
+		int t140code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->trtp), 1, ast_format_set(&tmp_fmt, AST_FORMAT_T140, 0), 0);
 		ast_str_append(a_buf, 0, "a=fmtp:%d %d/%d/%d\r\n", rtp_code,
 			 t140code,
 			 t140code,
@@ -10518,14 +10587,14 @@ static void add_noncodec_to_sdp(const struct sip_pvt *p, int format,
 	int rtp_code;
 
 	if (debug)
-		ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, format, 0));
-	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, format)) == -1)
+		ast_verbose("Adding non-codec 0x%x (%s) to SDP\n", format, ast_rtp_lookup_mime_subtype2(0, NULL, format, 0));
+	if ((rtp_code = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(p->rtp), 0, NULL, format)) == -1)
 		return;
 
 	ast_str_append(m_buf, 0, " %d", rtp_code);
 	ast_str_append(a_buf, 0, "a=rtpmap:%d %s/%d\r\n", rtp_code,
-		       ast_rtp_lookup_mime_subtype2(0, format, 0),
-		       ast_rtp_lookup_sample_rate2(0, format));
+		       ast_rtp_lookup_mime_subtype2(0, NULL, format, 0),
+		       ast_rtp_lookup_sample_rate2(0, NULL, format));
 	if (format == AST_RTP_DTMF)	/* Indicate we support DTMF and FLASH... */
 		ast_str_append(a_buf, 0, "a=fmtp:%d 0-16\r\n", rtp_code);
 }
@@ -10651,9 +10720,10 @@ static void get_crypto_attrib(struct sip_srtp *srtp, const char **a_crypto)
 */
 static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int oldsdp, int add_audio, int add_t38)
 {
-	format_t alreadysent = 0;
+	struct ast_format_cap *alreadysent = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *tmpcap = ast_format_cap_alloc_nolock();
+	int res = AST_SUCCESS;
 	int doing_directmedia = FALSE;
-
 	struct ast_sockaddr addr = { {0,} };
 	struct ast_sockaddr vaddr = { {0,} };
 	struct ast_sockaddr taddr = { {0,} };
@@ -10683,8 +10753,8 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 	const char *v_a_crypto = NULL;
 	const char *t_a_crypto = NULL;
 
-	format_t x;
-	format_t capability = 0;
+	int x;
+	struct ast_format tmp_fmt;
 	int needaudio = FALSE;
 	int needvideo = FALSE;
 	int needtext = FALSE;
@@ -10700,9 +10770,15 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 	/* Set the SDP session name */
 	snprintf(subject, sizeof(subject), "s=%s\r\n", ast_strlen_zero(global_sdpsession) ? "-" : global_sdpsession);
 
+	if (!alreadysent || !tmpcap) {
+		res = AST_FAILURE;
+		goto add_sdp_cleanup;
+	}
 	if (!p->rtp) {
 		ast_log(LOG_WARNING, "No way to add SDP without an RTP structure\n");
-		return AST_FAILURE;
+		res = AST_FAILURE;
+		goto add_sdp_cleanup;
+
 	}
 	/* XXX We should not change properties in the SIP dialog until
 		we have acceptance of the offer if this is a re-invite */
@@ -10717,9 +10793,9 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 	}
 
 	if (add_audio) {
-		doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && p->redircodecs) ? TRUE : FALSE;
+		doing_directmedia = (!ast_sockaddr_isnull(&p->redirip) && !(ast_format_cap_is_empty(p->redircaps))) ? TRUE : FALSE;
 		/* Check if we need video in this call */
-		if ((p->jointcapability & AST_FORMAT_VIDEO_MASK) && !p->novideo) {
+		if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_VIDEO)) && !p->novideo) {
 			if (p->vrtp) {
 				needvideo = TRUE;
 				ast_debug(2, "This call needs video offers!\n");
@@ -10727,7 +10803,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 				ast_debug(2, "This call needs video offers, but there's no video support enabled!\n");
 		}
 		/* Check if we need text in this call */
-		if ((p->jointcapability & AST_FORMAT_TEXT_MASK) && !p->notext) {
+		if ((ast_format_cap_has_type(p->jointcaps, AST_FORMAT_TYPE_TEXT)) && !p->notext) {
 			if (sipdebug_text)
 				ast_verbose("We think we can do text\n");
 			if (p->trtp) {
@@ -10767,20 +10843,20 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 			hold = "a=sendrecv\r\n";
 		}
 
-		capability = p->jointcapability;
+		ast_format_cap_copy(tmpcap, p->jointcaps);
 
 		/* XXX note, Video and Text are negated - 'true' means 'no' */
-		ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability),
+		ast_debug(1, "** Our capability: %s Video flag: %s Text flag: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap),
 			  p->novideo ? "True" : "False", p->notext ? "True" : "False");
-		ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcodec));
+		ast_debug(1, "** Our prefcodec: %s \n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), p->prefcaps));
 
 		if (doing_directmedia) {
-			capability &= p->redircodecs;
-			ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), capability));
+			ast_format_cap_joint_copy(p->jointcaps, p->redircaps, tmpcap);
+			ast_debug(1, "** Our native-bridge filtered capablity: %s\n", ast_getformatname_multiple(codecbuf, sizeof(codecbuf), tmpcap));
 		}
 
 		/* Check if we need audio */
-		if (capability & AST_FORMAT_AUDIO_MASK)
+		if (ast_format_cap_has_type(tmpcap, AST_FORMAT_TYPE_AUDIO))
 			needaudio = TRUE;
 
 		if (debug) {
@@ -10833,45 +10909,55 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 		/* Prefer the audio codec we were requested to use, first, no matter what
 		   Note that p->prefcodec can include video codecs, so mask them out
 		*/
-		if (capability & p->prefcodec) {
-			format_t codec = p->prefcodec & AST_FORMAT_AUDIO_MASK;
-
-			add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
-			alreadysent |= codec;
+		if (ast_format_cap_has_joint(tmpcap, p->prefcaps)) {
+			ast_format_cap_iter_start(p->prefcaps);
+			while (!(ast_format_cap_iter_next(p->prefcaps, &tmp_fmt))) {
+				if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) {
+					continue;
+				}
+				add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
+				ast_format_cap_add(alreadysent, &tmp_fmt);
+			}
+			ast_format_cap_iter_end(p->prefcaps);
 		}
 
 		/* Start by sending our preferred audio/video codecs */
-		for (x = 0; x < 64; x++) {
-			format_t codec;
-
-			if (!(codec = ast_codec_pref_index(&p->prefs, x)))
+		for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+			if (!(ast_codec_pref_index(&p->prefs, x, &tmp_fmt)))
 				break;
 
-			if (!(capability & codec))
+			if (!(ast_format_cap_iscompatible(tmpcap, &tmp_fmt)))
 				continue;
 
-			if (alreadysent & codec)
+			if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
 				continue;
 
-			add_codec_to_sdp(p, codec, &m_audio, &a_audio, debug, &min_audio_packet_size);
-			alreadysent |= codec;
+			if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
+				add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
+			} else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
+				add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
+			} else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
+				add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
+			}
+
+			ast_format_cap_add(alreadysent, &tmp_fmt);
 		}
 
 		/* Now send any other common audio and video codecs, and non-codec formats: */
-		for (x = 1ULL; x <= (needtext ? AST_FORMAT_TEXT_MASK : (needvideo ? AST_FORMAT_VIDEO_MASK : AST_FORMAT_AUDIO_MASK)); x <<= 1) {
-			if (!(capability & x))	/* Codec not requested */
+		ast_format_cap_iter_start(tmpcap);
+		while (!(ast_format_cap_iter_next(tmpcap, &tmp_fmt))) {
+			if (ast_format_cap_iscompatible(alreadysent, &tmp_fmt))
 				continue;
 
-			if (alreadysent & x)	/* Already added to SDP */
-				continue;
-
-			if (x & AST_FORMAT_AUDIO_MASK)
-				add_codec_to_sdp(p, x, &m_audio, &a_audio, debug, &min_audio_packet_size);
-			else if (x & AST_FORMAT_VIDEO_MASK)
-				add_vcodec_to_sdp(p, x, &m_video, &a_video, debug, &min_video_packet_size);
-			else if (x & AST_FORMAT_TEXT_MASK)
-				add_tcodec_to_sdp(p, x, &m_text, &a_text, debug, &min_text_packet_size);
+			if (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO) {
+				add_codec_to_sdp(p, &tmp_fmt, &m_audio, &a_audio, debug, &min_audio_packet_size);
+			} else if (needvideo && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_VIDEO)) {
+				add_vcodec_to_sdp(p, &tmp_fmt, &m_video, &a_video, debug, &min_video_packet_size);
+			} else if (needtext && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_TEXT)) {
+				add_tcodec_to_sdp(p, &tmp_fmt, &m_text, &a_text, debug, &min_text_packet_size);
+			}
 		}
+		ast_format_cap_iter_end(tmpcap);
 
 		/* Now add DTMF RFC2833 telephony-event as a codec */
 		for (x = 1LL; x <= AST_RTP_MAX; x <<= 1) {
@@ -11024,9 +11110,13 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int
 	ao2_t_unlink(dialogs_rtpcheck, p, "unlink pvt into dialogs_rtpcheck container");
 	ao2_t_link(dialogs_rtpcheck, p, "link pvt into dialogs_rtpcheck container");
 
-	ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, capability));
+	ast_debug(3, "Done building SDP. Settling with this capability: %s\n", ast_getformatname_multiple(buf, SIPBUFSIZE, tmpcap));
 
-	return AST_SUCCESS;
+add_sdp_cleanup:
+	alreadysent = ast_format_cap_destroy(alreadysent);
+	tmpcap = ast_format_cap_destroy(tmpcap);
+
+	return res;
 }
 
 /*! \brief Used for 200 OK and 183 early media */
@@ -15257,14 +15347,21 @@ static enum check_auth_result check_peer_ok(struct sip_pvt *p, char *of,
 		p->amaflags = peer->amaflags;
 		p->callgroup = peer->callgroup;
 		p->pickupgroup = peer->pickupgroup;
-		p->capability = peer->capability;
+		ast_format_cap_copy(p->caps, peer->caps);
+		ast_format_cap_copy(p->jointcaps, peer->caps);
 		p->prefs = peer->prefs;
-		p->jointcapability = peer->capability;
  		if (peer->maxforwards > 0) {
 			p->maxforwards = peer->maxforwards;
 		}
-		if (p->peercapability)
-			p->jointcapability &= p->peercapability;
+		if (!(ast_format_cap_is_empty(p->peercaps))) {
+			struct ast_format_cap *tmp = ast_format_cap_joint(p->jointcaps, p->peercaps);
+			struct ast_format_cap *tmp2;
+			if (tmp) {
+				tmp2 = p->jointcaps;
+				p->jointcaps = tmp;
+				ast_format_cap_destroy(tmp2);
+			}
+		}
 		p->maxcallbitrate = peer->maxcallbitrate;
 		if ((ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_RFC2833) ||
 		    (ast_test_flag(&p->flags[0], SIP_DTMF) == SIP_DTMF_AUTO))
@@ -16333,15 +16430,15 @@ static char *sip_prune_realtime(struct ast_cli_entry *e, int cmd, struct ast_cli
 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
 {
 	int x;
-	format_t codec;
+	struct ast_format codec;
 
-	for(x = 0; x < 64 ; x++) {
-		codec = ast_codec_pref_index(pref, x);
-		if (!codec)
+	for(x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!(ast_codec_pref_index(pref, x, &codec))) {
 			break;
-		ast_cli(fd, "%s", ast_getformatname(codec));
+		}
+		ast_cli(fd, "%s", ast_getformatname(&codec));
 		ast_cli(fd, ":%d", pref->framing[x]);
-		if (x < 31 && ast_codec_pref_index(pref, x + 1))
+		if (x < 31 && ast_codec_pref_index(pref, x + 1, &codec))
 			ast_cli(fd, ",");
 	}
 	if (!x)
@@ -16529,7 +16626,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
 	struct ast_variable *v;
 	struct sip_auth *auth;
 	int x = 0, load_realtime;
-	format_t codec = 0;
+	struct ast_format codec;
 	int realtimepeers;
 
 	realtimepeers = ast_check_realtime("sippeers");
@@ -16644,7 +16741,7 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
 
 		ast_cli(fd, "\n");
 		ast_cli(fd, "  Codecs       : ");
-		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
+		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
 		ast_cli(fd, "%s\n", codec_buf);
 		ast_cli(fd, "  Codec Order  : (");
 		print_codec_to_cli(fd, &peer->prefs);
@@ -16738,16 +16835,16 @@ static char *_sip_show_peer(int type, int fd, struct mansession *s, const struct
 		if (!ast_strlen_zero(sip_cfg.regcontext))
 			astman_append(s, "RegExtension: %s\r\n", peer->regexten);
 		astman_append(s, "Codecs: ");
-		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->capability);
+		ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, peer->caps);
 		astman_append(s, "%s\r\n", codec_buf);
 		astman_append(s, "CodecOrder: ");
 		pref = &peer->prefs;
-		for(x = 0; x < 64 ; x++) {
-			codec = ast_codec_pref_index(pref, x);
-			if (!codec)
+		for(x = 0; x < AST_CODEC_PREF_SIZE ; x++) {
+			if (!(ast_codec_pref_index(pref, x, &codec))) {
 				break;
-			astman_append(s, "%s", ast_getformatname(codec));
-			if (x < 63 && ast_codec_pref_index(pref, x+1))
+			}
+			astman_append(s, "%s", ast_getformatname(&codec));
+			if ((x < (AST_CODEC_PREF_SIZE - 1)) && ast_codec_pref_index(pref, x+1, &codec))
 				astman_append(s, ",");
 		}
 
@@ -17243,7 +17340,7 @@ static char *sip_show_settings(struct ast_cli_entry *e, int cmd, struct ast_cli_
 	ast_cli(a->fd, "\nGlobal Signalling Settings:\n");
 	ast_cli(a->fd, "---------------------------\n");
 	ast_cli(a->fd, "  Codecs:                 ");
-	ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.capability);
+	ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, sip_cfg.caps);
 	ast_cli(a->fd, "%s\n", codec_buf);
 	ast_cli(a->fd, "  Codec Order:            ");
 	print_codec_to_cli(a->fd, &default_prefs);
@@ -17400,7 +17497,7 @@ static int show_channels_cb(void *__cur, void *__arg, int flags)
 		ast_cli(arg->fd, FORMAT, ast_sockaddr_stringify_addr(dst),
 				S_OR(cur->username, S_OR(cur->cid_num, "(None)")),
 				cur->callid,
-				ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0),
+				cur->owner ? ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner->nativeformats) : "(nothing)",
 				AST_CLI_YESNO(ast_test_flag(&cur->flags[1], SIP_PAGE2_CALL_ONHOLD)),
 				cur->needdestroy ? "(d)" : "",
 				cur->lastmsg ,
@@ -17649,11 +17746,11 @@ static char *sip_show_channel(struct ast_cli_entry *e, int cmd, struct ast_cli_a
 			ast_cli(a->fd, "  Curr. trans. direction:  %s\n", ast_test_flag(&cur->flags[0], SIP_OUTGOING) ? "Outgoing" : "Incoming");
 			ast_cli(a->fd, "  Call-ID:                %s\n", cur->callid);
 			ast_cli(a->fd, "  Owner channel ID:       %s\n", cur->owner ? cur->owner->name : "<none>");
-			ast_cli(a->fd, "  Our Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->capability));
+			ast_cli(a->fd, "  Our Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->caps));
 			ast_cli(a->fd, "  Non-Codec Capability (DTMF):   %d\n", cur->noncodeccapability);
-			ast_cli(a->fd, "  Their Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercapability));
-			ast_cli(a->fd, "  Joint Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcapability));
-			ast_cli(a->fd, "  Format:                 %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner ? cur->owner->nativeformats : 0) );
+			ast_cli(a->fd, "  Their Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->peercaps));
+			ast_cli(a->fd, "  Joint Codec Capability:   %s\n", ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->jointcaps));
+			ast_cli(a->fd, "  Format:                 %s\n", cur->owner ? ast_getformatname_multiple(formatbuf, sizeof(formatbuf), cur->owner->nativeformats) : "(nothing)" );
 			ast_cli(a->fd, "  T.38 support            %s\n", AST_CLI_YESNO(cur->udptl != NULL));
 			ast_cli(a->fd, "  Video support           %s\n", AST_CLI_YESNO(cur->vrtp != NULL));
 			ast_cli(a->fd, "  MaxCallBR:              %d kbps\n", cur->maxcallbitrate);
@@ -18558,13 +18655,13 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
 	} else  if (!strcasecmp(colname, "callerid_num")) {
 		ast_copy_string(buf, peer->cid_num, len);
 	} else  if (!strcasecmp(colname, "codecs")) {
-		ast_getformatname_multiple(buf, len -1, peer->capability);
+		ast_getformatname_multiple(buf, len -1, peer->caps);
 	} else if (!strcasecmp(colname, "encryption")) {
 		snprintf(buf, len, "%d", ast_test_flag(&peer->flags[1], SIP_PAGE2_USE_SRTP));
 	} else  if (!strncasecmp(colname, "chanvar[", 8)) {
 		char *chanvar=colname + 8;
 		struct ast_variable *v;
-	
+
 		chanvar = strsep(&chanvar, "]");
 		for (v = peer->chanvars ; v ; v = v->next) {
 			if (!strcasecmp(v->name, chanvar)) {
@@ -18573,12 +18670,12 @@ static int function_sippeer(struct ast_channel *chan, const char *cmd, char *dat
 		}
 	} else  if (!strncasecmp(colname, "codec[", 6)) {
 		char *codecnum;
-		format_t codec = 0;
-		
+		struct ast_format codec;
+
 		codecnum = colname + 6;	/* move past the '[' */
 		codecnum = strsep(&codecnum, "]"); /* trim trailing ']' if any */
-		if((codec = ast_codec_pref_index(&peer->prefs, atoi(codecnum)))) {
-			ast_copy_string(buf, ast_getformatname(codec), len);
+		if((ast_codec_pref_index(&peer->prefs, atoi(codecnum), &codec))) {
+			ast_copy_string(buf, ast_getformatname(&codec), len);
 		} else {
 			buf[0] = '\0';
 		}
@@ -21484,7 +21581,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
 				}
 				ast_queue_control(p->owner, AST_CONTROL_SRCUPDATE);
 			} else {
-				p->jointcapability = p->capability;
+				ast_format_cap_copy(p->jointcaps, p->caps);
 				ast_debug(1, "Hm....  No sdp for the moment\n");
 				/* Some devices signal they want to be put off hold by sending a re-invite
 				   *without* an SDP, which is supposed to mean "Go back to your state"
@@ -21566,7 +21663,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
 				goto request_invite_cleanup;
 			}
 		} else {	/* No SDP in invite, call control session */
-			p->jointcapability = p->capability;
+			ast_format_cap_copy(p->jointcaps, p->caps);
 			ast_debug(2, "No SDP in Invite, third party call control\n");
 		}
 
@@ -21968,7 +22065,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
 		if (p && (p->autokillid == -1)) {
 			const char *msg;
 
-			if (!p->jointcapability)
+			if ((ast_format_cap_is_empty(p->jointcaps)))
 				msg = "488 Not Acceptable Here (codec error)";
 			else {
 				ast_log(LOG_NOTICE, "Unable to create/find SIP channel for this INVITE\n");
@@ -25309,12 +25406,13 @@ static int sip_devicestate(void *data)
  *	or	SIP/host!dnid
  * \endverbatim
 */
-static struct ast_channel *sip_request_call(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *sip_request_call(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct sip_pvt *p;
 	struct ast_channel *tmpc = NULL;
 	char *ext = NULL, *host;
 	char tmp[256];
+	char tmp2[256];
 	char *dest = data;
 	char *dnid;
 	char *secret = NULL;
@@ -25325,7 +25423,6 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
 	char *remote_address;
 	enum sip_transport transport = 0;
 	struct ast_sockaddr remote_address_sa = { {0,} };
-	format_t oldformat = format;
 	AST_DECLARE_APP_ARGS(args,
 		AST_APP_ARG(peerorhost);
 		AST_APP_ARG(exten);
@@ -25339,13 +25436,14 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
 	 * configured from sip.conf, and sip_tech.capabilities, which is
 	 * hardwired to all audio formats.
 	 */
-	format &= AST_FORMAT_AUDIO_MASK;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n", ast_getformatname(oldformat), ast_getformatname(sip_cfg.capability));
+	if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format %s while capability is %s\n",
+		ast_getformatname_multiple(tmp, sizeof(tmp), cap),
+		ast_getformatname_multiple(tmp2, sizeof(tmp2), sip_cfg.caps));
 		*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;	/* Can't find codec to connect to host */
 		return NULL;
 	}
-	ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), oldformat));
+	ast_debug(1, "Asked to create a SIP channel with formats: %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 
 	if (ast_strlen_zero(dest)) {
 		ast_log(LOG_ERROR, "Unable to create channel with empty destination.\n");
@@ -25488,8 +25586,9 @@ static struct ast_channel *sip_request_call(const char *type, format_t format, c
 #if 0
 	printf("Setting up to call extension '%s' at '%s'\n", ext ? ext : "<none>", host);
 #endif
-	p->prefcodec = oldformat;				/* Format for this call */
-	p->jointcapability = oldformat & p->capability;
+	ast_format_cap_append(p->prefcaps, cap);
+	ast_format_cap_joint_copy(cap, p->caps, p->jointcaps);
+
 	sip_pvt_lock(p);
 	tmpc = sip_new(p, AST_STATE_DOWN, host, requestor ? requestor->linkedid : NULL);	/* Place the call */
 	if (sip_cfg.callevents)
@@ -25915,7 +26014,7 @@ static void set_peer_defaults(struct sip_peer *peer)
 	ast_string_field_set(peer, engine, default_engine);
 	ast_sockaddr_setnull(&peer->addr);
 	ast_sockaddr_setnull(&peer->defaddr);
-	peer->capability = sip_cfg.capability;
+	ast_format_cap_copy(peer->caps, sip_cfg.caps);
 	peer->maxcallbitrate = default_maxcallbitrate;
 	peer->rtptimeout = global_rtptimeout;
 	peer->rtpholdtimeout = global_rtpholdtimeout;
@@ -26063,9 +26162,13 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 		if (!(peer->the_mark))
 			firstpass = 0;
 	} else {
-		if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct")))
+		if (!(peer = ao2_t_alloc(sizeof(*peer), sip_destroy_peer_fn, "allocate a peer struct"))) {
 			return NULL;
-
+		}
+		if (!(peer->caps = ast_format_cap_alloc_nolock())) {
+			ao2_t_ref(peer, -1, "failed to allocate format capabilities, drop peer");
+			return NULL;
+		}
 		if (ast_string_field_init(peer, 512)) {
 			ao2_t_ref(peer, -1, "failed to string_field_init, drop peer");
 			return NULL;
@@ -26356,12 +26459,12 @@ static struct sip_peer *build_peer(const char *name, struct ast_variable *v, str
 			} else if (!strcasecmp(v->name, "pickupgroup")) {
 				peer->pickupgroup = ast_get_group(v->value);
 			} else if (!strcasecmp(v->name, "allow")) {
-				int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, TRUE);
+				int error = ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, TRUE);
 				if (error) {
 					ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
 				}
 			} else if (!strcasecmp(v->name, "disallow")) {
-				int error =  ast_parse_allow_disallow(&peer->prefs, &peer->capability, v->value, FALSE);
+				int error =  ast_parse_allow_disallow(&peer->prefs, peer->caps, v->value, FALSE);
 				if (error) {
 					ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
 				}
@@ -26697,6 +26800,22 @@ static int peer_markall_func(void *device, void *arg, int flags)
 	return 0;
 }
 
+/*!
+ * \internal
+ * \brief If no default formats are set in config, these are used 
+ */
+static void sip_set_default_format_capabilities(struct ast_format_cap *cap)
+{
+	struct ast_format tmp_fmt;
+
+	ast_format_cap_remove_all(cap);
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_TESTLAW, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_H263, 0));
+}
+
 /*! \brief Re-read SIP.conf config file
 \note	This function reloads all config data, except for
 	active peers (with registrations). They will only
@@ -26852,7 +26971,7 @@ static int reload_config(enum channelreloadreason reason)
 	/* Reset channel settings to default before re-configuring */
 	sip_cfg.allow_external_domains = DEFAULT_ALLOW_EXT_DOM;				/* Allow external invites */
 	sip_cfg.regcontext[0] = '\0';
-	sip_cfg.capability = DEFAULT_CAPABILITY;
+	sip_set_default_format_capabilities(sip_cfg.caps);
 	sip_cfg.regextenonqualify = DEFAULT_REGEXTENONQUALIFY;
 	sip_cfg.notifyringing = DEFAULT_NOTIFYRINGING;
 	sip_cfg.notifycid = DEFAULT_NOTIFYCID;
@@ -27258,12 +27377,12 @@ static int reload_config(enum channelreloadreason reason)
 				ast_log(LOG_WARNING, "Invalid externtlsport value, must be a positive integer between 1 and 65535 at line %d\n", v->lineno);
 			}
 		} else if (!strcasecmp(v->name, "allow")) {
-			int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, TRUE);
+			int error =  ast_parse_allow_disallow(&default_prefs, sip_cfg.caps, v->value, TRUE);
 			if (error) {
 				ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
 			}
 		} else if (!strcasecmp(v->name, "disallow")) {
-			int error =  ast_parse_allow_disallow(&default_prefs, &sip_cfg.capability, v->value, FALSE);
+			int error =  ast_parse_allow_disallow(&default_prefs, sip_cfg.caps, v->value, FALSE);
 			if (error) {
 				ast_log(LOG_WARNING, "Codec configuration errors found in line %d : %s = %s\n", v->lineno, v->name, v->value);
 			}
@@ -27918,7 +28037,7 @@ static enum ast_rtp_glue_result sip_get_trtp_peer(struct ast_channel *chan, stru
 	return res;
 }
 
-static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active)
+static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active)
 {
 	struct sip_pvt *p;
 	int changed = 0;
@@ -27966,8 +28085,8 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
 		memset(&p->tredirip, 0, sizeof(p->tredirip));
 		changed = 1;
 	}
-	if (codecs && (p->redircodecs != codecs)) {
-		p->redircodecs = codecs;
+	if (cap && !(ast_format_cap_is_empty(cap) && !(ast_format_cap_identical(p->redircaps, cap)))) {
+		ast_format_cap_copy(p->redircaps, cap);
 		changed = 1;
 	}
 	if (changed && !ast_test_flag(&p->flags[0], SIP_GOTREFER) && !ast_test_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER)) {
@@ -27990,10 +28109,10 @@ static int sip_set_rtp_peer(struct ast_channel *chan, struct ast_rtp_instance *i
 	return 0;
 }
 
-static format_t sip_get_codec(struct ast_channel *chan)
+static void sip_get_codec(struct ast_channel *chan, struct ast_format_cap *result)
 {
 	struct sip_pvt *p = chan->tech_pvt;
-	return p->peercapability ? p->peercapability : p->capability;
+	ast_format_cap_append(result, ast_format_cap_is_empty(p->peercaps) ? p->caps : p->peercaps);
 }
 
 static struct ast_rtp_glue sip_rtp_glue = {
@@ -28955,7 +29074,7 @@ static int peers_data_provider_get(const struct ast_data_search *search,
 		ast_data_add_str(enum_node, "text", ast_describe_caller_presentation(peer->callingpres));
 
 		/* codecs */
-		ast_data_add_codecs(data_peer, "codecs", peer->capability);
+		ast_data_add_codecs(data_peer, "codecs", peer->caps);
 
 		if (!ast_data_search_match(search, data_peer)) {
 			ast_data_remove_node(data_root, data_peer);
@@ -28982,6 +29101,10 @@ static const struct ast_data_entry sip_data_providers[] = {
 static int load_module(void)
 {
 	ast_verbose("SIP channel loading...\n");
+
+	if (!(sip_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
 	/* the fact that ao2_containers can't resize automatically is a major worry! */
 	/* if the number of objects gets above MAX_XXX_BUCKETS, things will slow down */
 	peers = ao2_t_container_alloc(HASH_PEER_SIZE, peer_hash_cb, peer_cmp_cb, "allocate peers");
@@ -28990,7 +29113,12 @@ static int load_module(void)
 	dialogs_needdestroy = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs_needdestroy");
 	dialogs_rtpcheck = ao2_t_container_alloc(HASH_DIALOG_SIZE, dialog_hash_cb, dialog_cmp_cb, "allocate dialogs for rtpchecks");
 	threadt = ao2_t_container_alloc(HASH_DIALOG_SIZE, threadt_hash_cb, threadt_cmp_cb, "allocate threadt table");
-	
+
+	if (!(sip_cfg.caps = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_FAILURE;
+	}
+	ast_format_cap_add_all_by_type(sip_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+
 	ASTOBJ_CONTAINER_INIT(&regl); /* Registry object list -- not searched for anything */
 	ASTOBJ_CONTAINER_INIT(&submwil); /* MWI subscription object list */
 
@@ -29257,6 +29385,9 @@ static int unload_module(void)
 	sip_reqresp_parser_exit();
 	sip_unregister_tests();
 
+	ast_format_cap_destroy(sip_tech.capabilities);
+	sip_cfg.caps = ast_format_cap_destroy(sip_cfg.caps);
+
 	return 0;
 }
 
diff --git a/channels/chan_skinny.c b/channels/chan_skinny.c
index 0d75888bab30d4423143a7b11e7040bffefe17f8..3eb76820c9391d743f645323c09287199943d5d3 100644
--- a/channels/chan_skinny.c
+++ b/channels/chan_skinny.c
@@ -148,7 +148,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 static const char tdesc[] = "Skinny Client Control Protocol (Skinny)";
 static const char config[] = "skinny.conf";
 
-static format_t default_capability = AST_FORMAT_ULAW | AST_FORMAT_ALAW;
+static struct ast_format_cap *default_cap;
 static struct ast_codec_pref default_prefs;
 
 enum skinny_codecs {
@@ -296,7 +296,7 @@ struct onhook_message {
 
 #define CAPABILITIES_RES_MESSAGE 0x0010
 struct station_capabilities {
-	uint32_t codec;
+	uint32_t codec; /* skinny codec, not ast codec */
 	uint32_t frames;
 	union {
 		char res[8];
@@ -1244,9 +1244,9 @@ struct skinny_subchannel {
 	int instance;					\
 	int group;					\
 	int needdestroy;				\
-	format_t confcapability;				\
+	struct ast_format_cap *confcap;				\
 	struct ast_codec_pref confprefs;		\
-	format_t capability;					\
+	struct ast_format_cap *cap;					\
 	struct ast_codec_pref prefs;			\
 	int nonCodecCapability;				\
 	int onhooktime;					\
@@ -1282,8 +1282,6 @@ static struct skinny_line_options{
  	.instance = 0,
  	.directmedia = 0,
  	.nat = 0,
- 	.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
- 	.capability = 0,
 	.getforward = 0,
  	.needdestroy = 0,
 	.prune = 0,
@@ -1324,9 +1322,9 @@ struct skinny_addon {
 	int registered;						\
 	int lastlineinstance;					\
 	int lastcallreference;					\
-	format_t confcapability;					\
+	struct ast_format_cap *confcap;					\
 	struct ast_codec_pref confprefs;			\
-	format_t capability;						\
+	struct ast_format_cap *cap;						\
 	int earlyrtp;						\
 	int transfer;						\
 	int callwaiting;					\
@@ -1358,8 +1356,6 @@ static struct skinny_device_options {
  	.callwaiting = 1,
  	.mwiblink = 0,
  	.dnd = 0,
- 	.confcapability = AST_FORMAT_ULAW | AST_FORMAT_ALAW,
- 	.capability = 0,
 	.prune = 0,
 };
 static struct skinny_device_options *default_device = &default_device_struct;
@@ -1386,7 +1382,7 @@ struct skinnysession {
 	AST_LIST_ENTRY(skinnysession) list;
 };
 
-static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static AST_LIST_HEAD_STATIC(sessions, skinnysession);
 
 static int skinny_devicestate(void *data);
@@ -1402,10 +1398,9 @@ static int skinny_senddigit_end(struct ast_channel *ast, char digit, unsigned in
 static void mwi_event_cb(const struct ast_event *event, void *userdata);
 static int skinny_reload(void);
 
-static const struct ast_channel_tech skinny_tech = {
+static struct ast_channel_tech skinny_tech = {
 	.type = "Skinny",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_AUDIO_MASK,
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = skinny_request,
 	.devicestate = skinny_devicestate,
@@ -1424,6 +1419,55 @@ static const struct ast_channel_tech skinny_tech = {
 static int skinny_extensionstate_cb(char *context, char* exten, int state, void *data);
 static int skinny_transfer(struct skinny_subchannel *sub);
 
+static struct skinny_line *skinny_line_alloc(void)
+{
+	struct skinny_line *l;
+	if (!(l = ast_calloc(1, sizeof(*l)))) {
+		return NULL;
+	}
+
+	l->cap = ast_format_cap_alloc_nolock();
+	l->confcap = ast_format_cap_alloc_nolock();
+	if (!l->cap || !l->confcap) {
+		l->cap = ast_format_cap_destroy(l->cap);
+		l->confcap = ast_format_cap_destroy(l->confcap);
+		ast_free(l);
+		return NULL;
+	}
+	return l;
+}
+static struct skinny_line *skinny_line_destroy(struct skinny_line *l)
+{
+	l->cap = ast_format_cap_destroy(l->cap);
+	l->confcap = ast_format_cap_destroy(l->confcap);
+	ast_free(l);
+	return NULL;
+}
+static struct skinny_device *skinny_device_alloc(void)
+{
+	struct skinny_device *d;
+	if (!(d = ast_calloc(1, sizeof(*d)))) {
+		return NULL;
+	}
+
+	d->cap = ast_format_cap_alloc_nolock();
+	d->confcap = ast_format_cap_alloc_nolock();
+	if (!d->cap || !d->confcap) {
+		d->cap = ast_format_cap_destroy(d->cap);
+		d->confcap = ast_format_cap_destroy(d->confcap);
+		ast_free(d);
+		return NULL;
+	}
+	return d;
+}
+static struct skinny_device *skinny_device_destroy(struct skinny_device *d)
+{
+	d->cap = ast_format_cap_destroy(d->cap);
+	d->confcap = ast_format_cap_destroy(d->confcap);
+	ast_free(d);
+	return NULL;
+}
+
 static void *get_button_template(struct skinnysession *s, struct button_definition_template *btn)
 {
 	struct skinny_device *d = s->device;
@@ -1729,31 +1773,32 @@ static struct skinny_speeddial *find_speeddial_by_instance(struct skinny_device
 	return sd;
 }
 
-static format_t codec_skinny2ast(enum skinny_codecs skinnycodec)
+static struct ast_format *codec_skinny2ast(enum skinny_codecs skinnycodec, struct ast_format *result)
 {
 	switch (skinnycodec) {
 	case SKINNY_CODEC_ALAW:
-		return AST_FORMAT_ALAW;
+		return ast_format_set(result, AST_FORMAT_ALAW, 0);
 	case SKINNY_CODEC_ULAW:
-		return AST_FORMAT_ULAW;
+		return ast_format_set(result, AST_FORMAT_ULAW, 0);
 	case SKINNY_CODEC_G723_1:
-		return AST_FORMAT_G723_1;
+		return ast_format_set(result, AST_FORMAT_G723_1, 0);
 	case SKINNY_CODEC_G729A:
-		return AST_FORMAT_G729A;
+		return ast_format_set(result, AST_FORMAT_G729A, 0);
 	case SKINNY_CODEC_G726_32:
-		return AST_FORMAT_G726_AAL2; /* XXX Is this right? */
+		return ast_format_set(result, AST_FORMAT_G726_AAL2, 0); /* XXX Is this right? */
 	case SKINNY_CODEC_H261:
-		return AST_FORMAT_H261;
+		return ast_format_set(result, AST_FORMAT_H261, 0);
 	case SKINNY_CODEC_H263:
-		return AST_FORMAT_H263;
+		return ast_format_set(result, AST_FORMAT_H263 ,0);
 	default:
-		return 0;
+		ast_format_clear(result);
+		return result;
 	}
 }
 
-static int codec_ast2skinny(format_t astcodec)
+static int codec_ast2skinny(struct ast_format *astcodec)
 {
-	switch (astcodec) {
+	switch (astcodec->id) {
 	case AST_FORMAT_ALAW:
 		return SKINNY_CODEC_ALAW;
 	case AST_FORMAT_ULAW:
@@ -1924,7 +1969,7 @@ static int skinny_register(struct skinny_req *req, struct skinnysession *s)
 					ast_verb(1, "Line %s already connected to %s. Not connecting to %s.\n", l->name, l->device->name, d->name);
 				} else {
 					l->device = d;
-					l->capability = l->confcapability & d->capability;
+					ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
 					l->prefs = l->confprefs;
 					if (!l->prefs.order[0]) {
 						l->prefs = d->confprefs;
@@ -1971,8 +2016,8 @@ static int skinny_unregister(struct skinny_req *req, struct skinnysession *s)
 		AST_LIST_TRAVERSE(&d->lines, l, list) {
 			if (l->device == d) {
 				l->device = NULL;
-				l->capability = 0;
-				ast_parse_allow_disallow(&l->prefs, &l->capability, "all", 0);			
+				ast_format_cap_remove_all(l->cap);
+				ast_parse_allow_disallow(&l->prefs, l->cap, "all", 0);
 				l->instance = 0;
 				manager_event(EVENT_FLAG_SYSTEM, "PeerStatus", "ChannelType: Skinny\r\nPeer: Skinny/%s@%s\r\nPeerStatus: Unregistered\r\n", l->name, d->name);
 				unregister_exten(l);
@@ -2234,16 +2279,17 @@ static void transmit_connect(struct skinny_device *d, struct skinny_subchannel *
 	struct skinny_req *req;
 	struct skinny_line *l = sub->parent;
 	struct ast_format_list fmt;
+	struct ast_format tmpfmt;
 
 	if (!(req = req_alloc(sizeof(struct open_receive_channel_message), OPEN_RECEIVE_CHANNEL_MESSAGE)))
 		return;
-
-	fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
+	ast_best_codec(l->cap, &tmpfmt);
+	fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
 
 	req->data.openreceivechannel.conferenceId = htolel(sub->callid);
 	req->data.openreceivechannel.partyId = htolel(sub->callid);
 	req->data.openreceivechannel.packets = htolel(fmt.cur_ms);
-	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(fmt.bits));
+	req->data.openreceivechannel.capability = htolel(codec_ast2skinny(ast_format_set(&tmpfmt, fmt.id, 0)));
 	req->data.openreceivechannel.echo = htolel(0);
 	req->data.openreceivechannel.bitrate = htolel(0);
 	transmit_response(d, req);
@@ -2448,6 +2494,7 @@ static void transmit_stopmediatransmission(struct skinny_device *d, struct skinn
 static void transmit_startmediatransmission(struct skinny_device *d, struct skinny_subchannel *sub, struct sockaddr_in dest, struct ast_format_list fmt)
 {
 	struct skinny_req *req;
+	struct ast_format tmpfmt;
 
 	if (!(req = req_alloc(sizeof(struct start_media_transmission_message), START_MEDIA_TRANSMISSION_MESSAGE)))
 		return;
@@ -2457,7 +2504,7 @@ static void transmit_startmediatransmission(struct skinny_device *d, struct skin
 	req->data.startmedia.remoteIp = dest.sin_addr.s_addr;
 	req->data.startmedia.remotePort = htolel(ntohs(dest.sin_port));
 	req->data.startmedia.packetSize = htolel(fmt.cur_ms);
-	req->data.startmedia.payloadType = htolel(codec_ast2skinny(fmt.bits));
+	req->data.startmedia.payloadType = htolel(codec_ast2skinny(ast_format_set(&tmpfmt, fmt.id, 0)));
 	req->data.startmedia.qualifier.precedence = htolel(127);
 	req->data.startmedia.qualifier.vad = htolel(0);
 	req->data.startmedia.qualifier.packets = htolel(0);
@@ -2901,7 +2948,7 @@ static enum ast_rtp_glue_result skinny_get_rtp_peer(struct ast_channel *c, struc
 
 }
 
-static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, format_t codecs, int nat_active)
+static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *rtp, struct ast_rtp_instance *vrtp, struct ast_rtp_instance *trtp, const struct ast_format_cap *codecs, int nat_active)
 {
 	struct skinny_subchannel *sub;
 	struct skinny_line *l;
@@ -2925,6 +2972,7 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
 	d = l->device;
 
 	if (rtp){
+		struct ast_format tmpfmt;
 		ast_rtp_instance_get_remote_address(rtp, &them_tmp);
 		ast_sockaddr_to_sin(&them_tmp, &them);
 
@@ -2934,10 +2982,11 @@ static int skinny_set_rtp_peer(struct ast_channel *c, struct ast_rtp_instance *r
 		if (skinnydebug)
 			ast_verb(1, "Peerip = %s:%d\n", ast_inet_ntoa(them.sin_addr), ntohs(them.sin_port));
 
-		fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
+		ast_best_codec(l->cap, &tmpfmt);
+		fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
 
 		if (skinnydebug)
-			ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
+			ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(ast_format_set(&tmpfmt, fmt.id, 0)), fmt.cur_ms);
 
 		if (!(l->directmedia) || (l->nat)){
 			ast_rtp_instance_get_local_address(rtp, &us_tmp);
@@ -3195,15 +3244,16 @@ static char *device2str(int type)
 /*! \brief Print codec list from preference to CLI/manager */
 static void print_codec_to_cli(int fd, struct ast_codec_pref *pref)
 {
-	int x, codec;
+	int x;
+	struct ast_format tmpfmt;
 
 	for(x = 0; x < 32 ; x++) {
-		codec = ast_codec_pref_index(pref, x);
-		if (!codec)
+		ast_codec_pref_index(pref, x, &tmpfmt);
+		if (!tmpfmt.id)
 			break;
-		ast_cli(fd, "%s", ast_getformatname(codec));
+		ast_cli(fd, "%s", ast_getformatname(&tmpfmt));
 		ast_cli(fd, ":%d", pref->framing[x]);
-		if (x < 31 && ast_codec_pref_index(pref, x + 1))
+		if (x < 31 && ast_codec_pref_index(pref, x + 1, &tmpfmt))
 			ast_cli(fd, ",");
 	}
 	if (!x)
@@ -3358,10 +3408,10 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
 				ast_cli(fd, "Port:        %d\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
 				ast_cli(fd, "Device Type: %s\n", device2str(d->type));
 				ast_cli(fd, "Conf Codecs:");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcapability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->confcap);
 				ast_cli(fd, "%s\n", codec_buf);
 				ast_cli(fd, "Neg Codecs: ");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->capability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, d->cap);
 				ast_cli(fd, "%s\n", codec_buf);
 				ast_cli(fd, "Registered:  %s\n", (d->registered ? "Yes" : "No"));
 				ast_cli(fd, "Lines:       %d\n", numlines);
@@ -3392,10 +3442,10 @@ static char *_skinny_show_device(int type, int fd, struct mansession *s, const s
 				astman_append(s, "Port: %d\r\n", (d->session ? ntohs(d->session->sin.sin_port) : 0));
 				astman_append(s, "DeviceType: %s\r\n", device2str(d->type));
 				astman_append(s, "Codecs: ");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcapability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->confcap);
 				astman_append(s, "%s\r\n", codec_buf);
 				astman_append(s, "CodecOrder: ");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->capability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) -1, d->cap);
 				astman_append(s, "%s\r\n", codec_buf);
 				astman_append(s, "Devicestatus: %s\r\n", (d->registered?"registered":"unregistered"));
 				astman_append(s, "NumberOfLines: %d\r\n", numlines);
@@ -3587,7 +3637,7 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
 	struct skinny_device *d;
 	struct skinny_line *l;
 	struct ast_codec_pref *pref;
-	int x = 0, codec = 0;
+	int x = 0;
 	char codec_buf[512];
 	char group_buf[256];
 	char cbuf[256];
@@ -3648,10 +3698,10 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
 				ast_cli(fd, "Group:            %d\n", l->group);
 				ast_cli(fd, "Parkinglot:       %s\n", S_OR(l->parkinglot, "<not set>"));
 				ast_cli(fd, "Conf Codecs:      ");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
 				ast_cli(fd, "%s\n", codec_buf);
 				ast_cli(fd, "Neg Codecs:       ");
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->capability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->cap);
 				ast_cli(fd, "%s\n", codec_buf);
 				ast_cli(fd, "Codec Order:      (");
 				print_codec_to_cli(fd, &l->prefs);
@@ -3693,16 +3743,17 @@ static char *_skinny_show_line(int type, int fd, struct mansession *s, const str
 				astman_append(s, "immediate: %s\r\n", (l->immediate ? "Yes" : "No"));
 				astman_append(s, "Group: %d\r\n", l->group);
 				astman_append(s, "Parkinglot: %s\r\n", S_OR(l->parkinglot, "<not set>"));
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcapability);
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf) - 1, l->confcap);
 				astman_append(s, "Codecs: %s\r\n", codec_buf);
 				astman_append(s, "CodecOrder: ");
 				pref = &l->prefs;
 				for(x = 0; x < 32 ; x++) {
-					codec = ast_codec_pref_index(pref, x);
-					if (!codec)
+					struct ast_format tmpfmt;
+					ast_codec_pref_index(pref, x, &tmpfmt);
+					if (!tmpfmt.id)
 						break;
-					astman_append(s, "%s", ast_getformatname(codec));
-					if (x < 31 && ast_codec_pref_index(pref, x+1))
+					astman_append(s, "%s", ast_getformatname(&tmpfmt));
+					if (x < 31 && ast_codec_pref_index(pref, x+1, &tmpfmt))
 						astman_append(s, ",");
 				}
 				astman_append(s, "\r\n");
@@ -4221,11 +4272,11 @@ static struct ast_frame *skinny_rtp_read(struct skinny_subchannel *sub)
 	if (ast) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != ast->nativeformats) {
-				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(f->subclass.codec));
-				ast->nativeformats = f->subclass.codec;
-				ast_set_read_format(ast, ast->readformat);
-				ast_set_write_format(ast, ast->writeformat);
+			if (!(ast_format_cap_iscompatible(ast->nativeformats, &f->subclass.format))) {
+				ast_debug(1, "Oooh, format changed to %s\n", ast_getformatname(&f->subclass.format));
+				ast_format_cap_set(ast->nativeformats, &f->subclass.format);
+				ast_set_read_format(ast, &ast->readformat);
+				ast_set_write_format(ast, &ast->writeformat);
 			}
 		}
 	}
@@ -4254,13 +4305,13 @@ static int skinny_write(struct ast_channel *ast, struct ast_frame *frame)
 			return 0;
 		}
 	} else {
-		if (!(frame->subclass.codec & ast->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
 			char buf[256];
 			ast_log(LOG_WARNING, "Asked to transmit frame type %s, while native formats is %s (read/write = %s/%s)\n",
-				ast_getformatname(frame->subclass.codec),
+				ast_getformatname(&frame->subclass.format),
 				ast_getformatname_multiple(buf, sizeof(buf), ast->nativeformats),
-				ast_getformatname(ast->readformat),
-				ast_getformatname(ast->writeformat));
+				ast_getformatname(&ast->readformat),
+				ast_getformatname(&ast->writeformat));
 			return -1;
 		}
 	}
@@ -4586,7 +4637,7 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
 	struct skinny_subchannel *sub;
 	struct skinny_device *d = l->device;
 	struct ast_variable *v = NULL;
-	int fmt;
+	struct ast_format tmpfmt;
 
 	if (!l->device) {
 		ast_log(LOG_WARNING, "Device for line %s is not registered.\n", l->name);
@@ -4622,16 +4673,17 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
 		}
 		tmp->tech = &skinny_tech;
 		tmp->tech_pvt = sub;
-		tmp->nativeformats = l->capability;
-		if (!tmp->nativeformats)
+		ast_format_cap_copy(tmp->nativeformats, l->cap);
+		if (ast_format_cap_is_empty(tmp->nativeformats)) {
 			// Should throw an error
-			tmp->nativeformats = default_capability;
-		fmt = ast_best_codec(tmp->nativeformats);
+			ast_format_cap_copy(tmp->nativeformats, default_cap);
+		}
+		ast_best_codec(tmp->nativeformats, &tmpfmt);
 		if (skinnydebug) {
 			char buf[256];
 			ast_verb(1, "skinny_new: tmp->nativeformats=%s fmt=%s\n",
 				ast_getformatname_multiple(buf, sizeof(buf), tmp->nativeformats),
-				ast_getformatname(fmt));
+				ast_getformatname(&tmpfmt));
 		}
 		if (sub->rtp) {
 			ast_channel_set_fd(tmp, 0, ast_rtp_instance_fd(sub->rtp, 0));
@@ -4639,10 +4691,11 @@ static struct ast_channel *skinny_new(struct skinny_line *l, int state, const ch
 		if (state == AST_STATE_RING) {
 			tmp->rings = 1;
 		}
-		tmp->writeformat = fmt;
-		tmp->rawwriteformat = fmt;
-		tmp->readformat = fmt;
-		tmp->rawreadformat = fmt;
+		ast_format_copy(&tmp->writeformat, &tmpfmt);
+		ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+		ast_format_copy(&tmp->readformat, &tmpfmt);
+		ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+
 		if (!ast_strlen_zero(l->language))
 			ast_string_field_set(tmp, language, l->language);
 		if (!ast_strlen_zero(l->accountcode))
@@ -5469,10 +5522,14 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
 	struct skinny_device *d = s->device;
 	struct skinny_line *l;
 	uint32_t count = 0;
-	format_t codecs = 0;
+	struct ast_format_cap *codecs = ast_format_cap_alloc();
 	int i;
 	char buf[256];
 
+	if (!codecs) {
+		return 0;
+	}
+
 	count = letohl(req->data.caps.count);
 	if (count > SKINNY_MAX_CAPABILITIES) {
 		count = SKINNY_MAX_CAPABILITIES;
@@ -5480,23 +5537,24 @@ static int handle_capabilities_res_message(struct skinny_req *req, struct skinny
 	}
 
 	for (i = 0; i < count; i++) {
-		format_t acodec = 0;
+		struct ast_format acodec;
 		int scodec = 0;
 		scodec = letohl(req->data.caps.caps[i].codec);
-		acodec = codec_skinny2ast(scodec);
+		codec_skinny2ast(scodec, &acodec);
 		if (skinnydebug)
-			ast_verb(1, "Adding codec capability '%" PRId64 " (%d)'\n", acodec, scodec);
-		codecs |= acodec;
+			ast_verb(1, "Adding codec capability %s (%d)'\n", ast_getformatname(&acodec), scodec);
+		ast_format_cap_add(codecs, &acodec);
 	}
 
-	d->capability = d->confcapability & codecs;
-	ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->capability));
+	ast_format_cap_joint_copy(d->confcap, codecs, d->cap);
+	ast_verb(0, "Device capability set to '%s'\n", ast_getformatname_multiple(buf, sizeof(buf), d->cap));
 	AST_LIST_TRAVERSE(&d->lines, l, list) {
 		ast_mutex_lock(&l->lock);
-		l->capability = l->confcapability & d->capability;
+		ast_format_cap_joint_copy(l->confcap, d->cap, l->cap);
 		ast_mutex_unlock(&l->lock);
 	}
 
+	codecs = ast_format_cap_destroy(codecs);
 	return 1;
 }
 
@@ -5658,6 +5716,7 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
 	struct sockaddr_in us = { 0, };
 	struct ast_sockaddr sin_tmp;
 	struct ast_sockaddr us_tmp;
+	struct ast_format tmpfmt;
 	uint32_t addr;
 	int port;
 	int status;
@@ -5698,11 +5757,11 @@ static int handle_open_receive_channel_ack_message(struct skinny_req *req, struc
 		ast_verb(1, "device ipaddr = %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
 		ast_verb(1, "asterisk ipaddr = %s:%d\n", ast_inet_ntoa(us.sin_addr), ntohs(us.sin_port));
 	}
-
-	fmt = ast_codec_pref_getsize(&l->prefs, ast_best_codec(l->capability));
+	ast_best_codec(l->cap, &tmpfmt);
+	fmt = ast_codec_pref_getsize(&l->prefs, &tmpfmt);
 
 	if (skinnydebug)
-		ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(fmt.bits), fmt.cur_ms);
+		ast_verb(1, "Setting payloadType to '%s' (%d ms)\n", ast_getformatname(ast_format_set(&tmpfmt, fmt.id, 0)), fmt.cur_ms);
 
 	transmit_startmediatransmission(d, sub, us, fmt);
 
@@ -6546,19 +6605,15 @@ static int skinny_devicestate(void *data)
 	return get_devicestate(l);
 }
 
-static struct ast_channel *skinny_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *skinny_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
-	format_t oldformat;
-	
 	struct skinny_line *l;
 	struct ast_channel *tmpc = NULL;
 	char tmp[256];
 	char *dest = data;
 
-	oldformat = format;
-	
-	if (!(format &= AST_FORMAT_AUDIO_MASK)) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), format));
+	if (!(ast_format_cap_has_type(cap, AST_FORMAT_TYPE_AUDIO))) {
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		return NULL;
 	}
 
@@ -6670,10 +6725,10 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
  				}
  				continue;
  			} else if (!strcasecmp(v->name, "allow")) {
- 				ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 1);
+ 				ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 1);
  				continue;
  			} else if (!strcasecmp(v->name, "disallow")) {
- 				ast_parse_allow_disallow(&default_prefs, &default_capability, v->value, 0);
+ 				ast_parse_allow_disallow(&default_prefs, default_cap, v->value, 0);
  				continue;
  			} 
  		}
@@ -6860,20 +6915,20 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
  			}
  		} else if (!strcasecmp(v->name, "allow")) {
  			if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- 				ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 1);
+ 				ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 1);
  				continue;
  			}
  			if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- 				ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 1);
+ 				ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 1);
  				continue;
  			}
  		} else if (!strcasecmp(v->name, "disallow")) {
  			if (type & (TYPE_DEF_DEVICE | TYPE_DEVICE)) {
- 				ast_parse_allow_disallow(&CDEV_OPTS->confprefs, &CDEV_OPTS->confcapability, v->value, 0);
+ 				ast_parse_allow_disallow(&CDEV_OPTS->confprefs, CDEV_OPTS->confcap, v->value, 0);
  				continue;
  			}
  			if (type & (TYPE_DEF_LINE | TYPE_LINE)) {
- 				ast_parse_allow_disallow(&CLINE_OPTS->confprefs, &CLINE_OPTS->confcapability, v->value, 0);
+ 				ast_parse_allow_disallow(&CLINE_OPTS->confprefs, CLINE_OPTS->confcap, v->value, 0);
  				continue;
  			}
  		} else if (!strcasecmp(v->name, "version")) {
@@ -6982,7 +7037,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
  		}
  	}
 
- 	if (!(l=ast_calloc(1, sizeof(*l)))) {
+ 	if (!(l = skinny_line_alloc())) {
  		ast_verb(1, "Unable to allocate memory for line %s.\n", lname);
  		AST_LIST_UNLOCK(&lines);
  		return NULL;
@@ -7040,7 +7095,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
  		}
  	}
 
- 	if (!(d = ast_calloc(1, sizeof(*d)))) {
+ 	if (!(d = skinny_device_alloc())) {
  		ast_verb(1, "Unable to allocate memory for device %s.\n", dname);
  		AST_LIST_UNLOCK(&devices);
  		return NULL;
@@ -7162,7 +7217,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
 	bindaddr.sin_family = AF_INET;
 
 	/* load the lines sections */
-	default_line->confcapability = default_capability;
+	ast_format_cap_copy(default_line->confcap, default_cap);
 	default_line->confprefs = default_prefs;
 	config_parse_variables(TYPE_DEF_LINE, default_line, ast_variable_browse(cfg, "lines"));
 	cat = ast_category_browse(cfg, "lines");
@@ -7172,7 +7227,7 @@ static struct ast_channel *skinny_request(const char *type, format_t format, con
 	}
 		
 	/* load the devices sections */
-	default_device->confcapability = default_capability;
+	ast_format_cap_copy(default_device->confcap, default_cap);
 	default_device->confprefs = default_prefs;
 	config_parse_variables(TYPE_DEF_DEVICE, default_device, ast_variable_browse(cfg, "devices"));
 	cat = ast_category_browse(cfg, "devices");
@@ -7243,7 +7298,7 @@ static void delete_devices(void)
 		/* Delete all lines for this device */
 		while ((l = AST_LIST_REMOVE_HEAD(&d->lines, list))) {
 			AST_LIST_REMOVE(&lines, l, all);
-			free(l);
+			l = skinny_line_destroy(l);
 		}
 		/* Delete all speeddials for this device */
 		while ((sd = AST_LIST_REMOVE_HEAD(&d->speeddials, list))) {
@@ -7252,8 +7307,8 @@ static void delete_devices(void)
 		/* Delete all addons for this device */
 		while ((a = AST_LIST_REMOVE_HEAD(&d->addons, list))) {
 			free(a);
-		} 
-		free(d);
+		}
+		d = skinny_device_destroy(d);
 	}
 	AST_LIST_UNLOCK(&lines);
 	AST_LIST_UNLOCK(&devices);
@@ -7310,7 +7365,7 @@ int skinny_reload(void)
 			free(a);
 		}
 		AST_LIST_REMOVE_CURRENT(list);
-		free(d);
+		d = skinny_device_destroy(d);
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
 	AST_LIST_UNLOCK(&devices);
@@ -7319,7 +7374,7 @@ int skinny_reload(void)
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&lines, l, all) {
 		if (l->prune) {
 			AST_LIST_REMOVE_CURRENT(all);
-			free(l);
+			l = skinny_line_destroy(l);
 		}
 	}
 	AST_LIST_TRAVERSE_SAFE_END;
@@ -7344,6 +7399,33 @@ int skinny_reload(void)
 static int load_module(void)
 {
 	int res = 0;
+	struct ast_format tmpfmt;
+	if (!(default_cap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(skinny_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(default_line->confcap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(default_line->cap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(default_device->confcap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(default_device->cap = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+
+	ast_format_cap_add_all_by_type(skinny_tech.capabilities, AST_FORMAT_TYPE_AUDIO);
+	ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(default_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(default_line->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(default_device->confcap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
 
 	for (; res < ARRAY_LEN(soft_key_template_default); res++) {
 		soft_key_template_default[res].softKeyEvent = htolel(soft_key_template_default[res].softKeyEvent);
@@ -7456,7 +7538,13 @@ static int unload_module(void)
 	con = ast_context_find(used_context);
 	if (con)
 		ast_context_destroy(con, "Skinny");
-	
+
+	default_cap = ast_format_cap_destroy(default_cap);
+	skinny_tech.capabilities = ast_format_cap_destroy(skinny_tech.capabilities);
+	default_line->confcap = ast_format_cap_destroy(default_line->confcap);
+	default_line->cap = ast_format_cap_destroy(default_line->cap);
+	default_device->confcap = ast_format_cap_destroy(default_device->confcap);
+	default_device->cap = ast_format_cap_destroy(default_device->cap);
 	return 0;
 }
 
diff --git a/channels/chan_unistim.c b/channels/chan_unistim.c
index 15589025012379aeceafd6d4c67b9744606e5066..4cb5dd71aecae7985725b28b4f5a712291706837 100644
--- a/channels/chan_unistim.c
+++ b/channels/chan_unistim.c
@@ -71,7 +71,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/indications.h"
 
 /*! Beware, G729 and G723 are not supported by asterisk, except with the proper licence */
-#define CAPABILITY AST_FORMAT_ALAW | AST_FORMAT_ULAW    /* | AST_FORMAT_G729A | AST_FORMAT_G723_1 */
 
 #define DEFAULTCONTEXT	  "default"
 #define DEFAULTCALLERID	 "Unknown"
@@ -102,6 +101,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #define SUB_THREEWAY	    1
 #define MAX_SUBS		2
 
+struct ast_format_cap *global_cap;
+
 enum autoprovision {
 	AUTOPROVISIONING_NO = 0,
 	AUTOPROVISIONING_YES,
@@ -409,7 +410,7 @@ struct unistim_line {
 	/*! AMA flags (for billing) */
 	int amaflags;
 	/*! Codec supported */
-	format_t capability;
+	struct ast_format_cap *cap;
 	/*! Parkinglot */
 	char parkinglot[AST_MAX_CONTEXT];
 	struct unistim_line *next;
@@ -679,7 +680,7 @@ static int reload(void);
 static int unload_module(void);
 static int reload_config(void);
 static void show_main_page(struct unistimsession *pte);
-static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor, 
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, 
 	void *data, int *cause);
 static int unistim_call(struct ast_channel *ast, char *dest, int timeout);
 static int unistim_hangup(struct ast_channel *ast);
@@ -698,10 +699,9 @@ static int write_entry_history(struct unistimsession *pte, FILE * f, char c,
 	char *line1);
 static void change_callerid(struct unistimsession *pte, int type, char *callerid);
 
-static const struct ast_channel_tech unistim_tech = {
+static struct ast_channel_tech unistim_tech = {
 	.type = channel_type,
 	.description = tdesc,
-	.capabilities = CAPABILITY,
 	.properties = AST_CHAN_TP_WANTSJITTER | AST_CHAN_TP_CREATESJITTER,
 	.requester = unistim_request,
 	.call = unistim_call,
@@ -1483,6 +1483,38 @@ static int unistim_register(struct unistimsession *s)
 	return 1;
 }
 
+static void unistim_line_copy(struct unistim_line *dst, struct unistim_line *src)
+{
+	struct ast_format_cap *tmp = src->cap;
+	memcpy(dst, src, sizeof(*dst)); /* this over writes the cap ptr, so we have to reset it */
+	src->cap = tmp;
+	ast_format_cap_copy(src->cap, dst->cap);
+}
+
+static struct unistim_line *unistim_line_destroy(struct unistim_line *l)
+{
+	if (!l) {
+		return NULL;
+	}
+	l->cap = ast_format_cap_destroy(l->cap);
+	ast_free(l);
+	return NULL;
+}
+
+static struct unistim_line *unistim_line_alloc(void)
+{
+	struct unistim_line *l;
+	if (!(l = ast_calloc(1, sizeof(*l)))) {
+		return NULL;
+	}
+
+	if (!(l->cap = ast_format_cap_alloc_nolock())) {
+		ast_free(l);
+		return NULL;
+	}
+	return l;
+}
+
 static int alloc_sub(struct unistim_line *l, int x)
 {
 	struct unistim_subchannel *sub;
@@ -1554,16 +1586,16 @@ static void rcv_mac_addr(struct unistimsession *pte, const unsigned char *buf)
 						}
 
 						memcpy(newd, d, sizeof(*newd));
-						if (!(newl = ast_malloc(sizeof(*newl)))) {
+						if (!(newl = unistim_line_alloc())) {
 							ast_free(newd);
 							ast_mutex_unlock(&devicelock);
 							return;
 						}
 
-						memcpy(newl, d->lines, sizeof(*newl));
+						unistim_line_copy(d->lines, newl);
 						if (!alloc_sub(newl, SUB_REAL)) {
 							ast_free(newd);
-							ast_free(newl);
+							unistim_line_destroy(newl);
 							ast_mutex_unlock(&devicelock);
 							return;
 						}
@@ -2038,7 +2070,7 @@ static void start_rtp(struct unistim_subchannel *sub)
 	struct sockaddr_in us = { 0, };
 	struct sockaddr_in public = { 0, };
 	struct sockaddr_in sin = { 0, };
-	format_t codec;
+	int codec;
 	struct sockaddr_in sout = { 0, };
 	struct ast_sockaddr us_tmp;
 	struct ast_sockaddr sin_tmp;
@@ -2093,19 +2125,19 @@ static void start_rtp(struct unistim_subchannel *sub)
 	sin.sin_port = htons(sub->parent->parent->rtp_port);
 	ast_sockaddr_from_sin(&sin_tmp, &sin);
 	ast_rtp_instance_set_remote_address(sub->rtp, &sin_tmp);
-	if (!(sub->owner->nativeformats & sub->owner->readformat)) {
-		format_t fmt;
+	if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &sub->owner->readformat))) {
+		struct ast_format tmpfmt;
 		char tmp[256];
-		fmt = ast_best_codec(sub->owner->nativeformats);
+		ast_best_codec(sub->owner->nativeformats, &tmpfmt);
 		ast_log(LOG_WARNING,
 				"Our read/writeformat has been changed to something incompatible: %s, using %s best codec from %s\n",
-				ast_getformatname(sub->owner->readformat),
-				ast_getformatname(fmt),
+				ast_getformatname(&sub->owner->readformat),
+				ast_getformatname(&tmpfmt),
 				ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats));
-		sub->owner->readformat = fmt;
-		sub->owner->writeformat = fmt;
+		ast_format_copy(&sub->owner->readformat, &tmpfmt);
+		ast_format_copy(&sub->owner->writeformat, &tmpfmt);
 	}
-	codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, sub->owner->readformat);
+	codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(sub->rtp), 1, &sub->owner->readformat, 0);
 	/* 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  */
@@ -2114,14 +2146,14 @@ static void start_rtp(struct unistim_subchannel *sub)
 	if (unistimdebug) {
 		ast_verb(0, "RTP started : Our IP/port is : %s:%hd with codec %s\n",
 			 ast_inet_ntoa(us.sin_addr),
-			 htons(us.sin_port), ast_getformatname(sub->owner->readformat));
+			 htons(us.sin_port), ast_getformatname(&sub->owner->readformat));
 		ast_verb(0, "Starting phone RTP stack. Our public IP is %s\n",
 					ast_inet_ntoa(public.sin_addr));
 	}
-	if ((sub->owner->readformat == AST_FORMAT_ULAW) ||
-		(sub->owner->readformat == AST_FORMAT_ALAW)) {
+	if ((sub->owner->readformat.id == AST_FORMAT_ULAW) ||
+		(sub->owner->readformat.id == AST_FORMAT_ALAW)) {
 		if (unistimdebug)
-			ast_verb(0, "Sending packet_send_rtp_packet_size for codec %s\n", ast_getformatname(codec));
+			ast_verb(0, "Sending packet_send_rtp_packet_size for codec %d\n", codec);
 		memcpy(buffsend + SIZE_HEADER, packet_send_rtp_packet_size,
 			   sizeof(packet_send_rtp_packet_size));
 		buffsend[10] = (int) codec & 0xffffffffLL;
@@ -2214,17 +2246,17 @@ static void start_rtp(struct unistim_subchannel *sub)
 		/* Codec */
 		buffsend[40] = codec;
 		buffsend[41] = codec;
-		if (sub->owner->readformat == AST_FORMAT_ULAW)
+		if (sub->owner->readformat.id == AST_FORMAT_ULAW)
 			buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
-		else if (sub->owner->readformat == AST_FORMAT_ALAW)
+		else if (sub->owner->readformat.id == AST_FORMAT_ALAW)
 			buffsend[42] = 1;       /* 1 = 20ms (160 bytes), 2 = 40ms (320 bytes) */
-		else if (sub->owner->readformat == AST_FORMAT_G723_1)
+		else if (sub->owner->readformat.id == AST_FORMAT_G723_1)
 			buffsend[42] = 2;       /* 1 = 30ms (24 bytes), 2 = 60 ms (48 bytes) */
-		else if (sub->owner->readformat == AST_FORMAT_G729A)
+		else if (sub->owner->readformat.id == AST_FORMAT_G729A)
 			buffsend[42] = 2;       /* 1 = 10ms (10 bytes), 2 = 20ms (20 bytes) */
 		else
 			ast_log(LOG_WARNING, "Unsupported codec %s!\n",
-					ast_getformatname(sub->owner->readformat));
+					ast_getformatname(&sub->owner->readformat));
 		/* Source port for transmit RTP and Destination port for receiving RTP */
 		buffsend[45] = (htons(sin.sin_port) & 0xff00) >> 8;
 		buffsend[46] = (htons(sin.sin_port) & 0x00ff);
@@ -4005,15 +4037,16 @@ static struct ast_frame *unistim_rtp_read(const struct ast_channel *ast,
 	if (sub->owner) {
 		/* We already hold the channel lock */
 		if (f->frametype == AST_FRAME_VOICE) {
-			if (f->subclass.codec != sub->owner->nativeformats) {
+			if (!(ast_format_cap_iscompatible(sub->owner->nativeformats, &f->subclass.format))) {
+				char tmp[256];
 				ast_debug(1,
 						"Oooh, format changed from %s to %s\n",
-						ast_getformatname(sub->owner->nativeformats),
-						ast_getformatname(f->subclass.codec));
+						ast_getformatname_multiple(tmp, sizeof(tmp), sub->owner->nativeformats),
+						ast_getformatname(&f->subclass.format));
 
-				sub->owner->nativeformats = f->subclass.codec;
-				ast_set_read_format(sub->owner, sub->owner->readformat);
-				ast_set_write_format(sub->owner, sub->owner->writeformat);
+				ast_format_cap_set(sub->owner->nativeformats, &f->subclass.format);
+				ast_set_read_format(sub->owner, &sub->owner->readformat);
+				ast_set_write_format(sub->owner, &sub->owner->writeformat);
 			}
 		}
 	}
@@ -4047,14 +4080,14 @@ static int unistim_write(struct ast_channel *ast, struct ast_frame *frame)
 			return 0;
 		}
 	} else {
-		if (!(frame->subclass.codec & ast->nativeformats)) {
+		if (!(ast_format_cap_iscompatible(ast->nativeformats, &frame->subclass.format))) {
 			char tmp[256];
 			ast_log(LOG_WARNING,
 					"Asked to transmit frame type %s, while native formats is %s (read/write = (%s/%s)\n",
-					ast_getformatname(frame->subclass.codec),
+					ast_getformatname(&frame->subclass.format),
 					ast_getformatname_multiple(tmp, sizeof(tmp), ast->nativeformats),
-					ast_getformatname(ast->readformat),
-					ast_getformatname(ast->writeformat));
+					ast_getformatname(&ast->readformat),
+					ast_getformatname(&ast->writeformat));
 			return -1;
 		}
 	}
@@ -4499,7 +4532,7 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
 {
 	struct ast_channel *tmp;
 	struct unistim_line *l;
-	int fmt;
+	struct ast_format tmpfmt;
 
 	if (!sub) {
 		ast_log(LOG_WARNING, "subchannel null in unistim_new\n");
@@ -4519,17 +4552,17 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
 		return NULL;
 	}
 
-	tmp->nativeformats = l->capability;
-	if (!tmp->nativeformats)
-		tmp->nativeformats = CAPABILITY;
-	fmt = ast_best_codec(tmp->nativeformats);
+	ast_format_cap_copy(tmp->nativeformats, l->cap);
+	if (ast_format_cap_is_empty(tmp->nativeformats))
+		ast_format_cap_copy(tmp->nativeformats, global_cap);
+	ast_best_codec(tmp->nativeformats, &tmpfmt);
 	if (unistimdebug) {
 		char tmp1[256], tmp2[256], tmp3[256];
 		ast_verb(0, "Best codec = %s from nativeformats %s (line cap=%s global=%s)\n",
-			ast_getformatname(fmt),
+			ast_getformatname(&tmpfmt),
 			ast_getformatname_multiple(tmp1, sizeof(tmp1), tmp->nativeformats),
-			ast_getformatname_multiple(tmp2, sizeof(tmp2), l->capability),
-			ast_getformatname_multiple(tmp3, sizeof(tmp3), CAPABILITY));
+			ast_getformatname_multiple(tmp2, sizeof(tmp2), l->cap),
+			ast_getformatname_multiple(tmp3, sizeof(tmp3), global_cap));
 	}
 	if ((sub->rtp) && (sub->subtype == 0)) {
 		if (unistimdebug)
@@ -4545,10 +4578,10 @@ static struct ast_channel *unistim_new(struct unistim_subchannel *sub, int state
 	if (state == AST_STATE_RING)
 		tmp->rings = 1;
 	tmp->adsicpe = AST_ADSI_UNAVAILABLE;
-	tmp->writeformat = fmt;
-	tmp->rawwriteformat = fmt;
-	tmp->readformat = fmt;
-	tmp->rawreadformat = fmt;
+	ast_format_copy(&tmp->writeformat, &tmpfmt);
+	ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
+	ast_format_copy(&tmp->readformat, &tmpfmt);
+	ast_format_copy(&tmp->rawreadformat, &tmpfmt);
 	tmp->tech_pvt = sub;
 	tmp->tech = &unistim_tech;
 	if (!ast_strlen_zero(l->language))
@@ -4699,26 +4732,19 @@ static int restart_monitor(void)
 
 /*--- unistim_request: PBX interface function ---*/
 /* UNISTIM calls initiated by the PBX arrive here */
-static struct ast_channel *unistim_request(const char *type, format_t format, const struct ast_channel *requestor, void *data,
+static struct ast_channel *unistim_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data,
 										   int *cause)
 {
-	format_t oldformat;
 	struct unistim_subchannel *sub;
 	struct ast_channel *tmpc = NULL;
 	char tmp[256];
+	char tmp2[256];
 	char *dest = data;
 
-	oldformat = format;
-	format &= CAPABILITY;
-	ast_log(LOG_NOTICE,
-			"Asked to get a channel of format %s while capability is %s result : %s\n",
-			ast_getformatname(oldformat),
-			ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY),
-			ast_getformatname(format));
-	if (!format) {
+	if (!(ast_format_cap_has_joint(cap, global_cap))) {
 		ast_log(LOG_NOTICE,
 				"Asked to get a channel of unsupported format %s while capability is %s\n",
-				ast_getformatname(oldformat), ast_getformatname_multiple(tmp, sizeof(tmp), CAPABILITY));
+				ast_getformatname_multiple(tmp2, sizeof(tmp2), cap), ast_getformatname_multiple(tmp, sizeof(tmp), global_cap));
 		return NULL;
 	}
 
@@ -4743,7 +4769,7 @@ static struct ast_channel *unistim_request(const char *type, format_t format, co
 		*cause = AST_CAUSE_BUSY;
 		return NULL;
 	}
-	sub->parent->capability = format;
+	ast_format_cap_copy(sub->parent->cap, cap);
 	tmpc = unistim_new(sub, AST_STATE_DOWN, requestor ? requestor->linkedid : NULL);
 	if (!tmpc)
 		ast_log(LOG_WARNING, "Unable to make channel for '%s'\n", tmp);
@@ -4786,10 +4812,11 @@ static char *unistim_info(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 				device);
 		line = device->lines;
 		while (line) {
+			char tmp2[256];
 			ast_cli(a->fd,
-					"->name=%s fullname=%s exten=%s callid=%s cap=%" PRId64 " device=%p line=%p\n",
+					"->name=%s fullname=%s exten=%s callid=%s cap=%s device=%p line=%p\n",
 					line->name, line->fullname, line->exten, line->cid_num,
-					line->capability, line->parent, line);
+					ast_getformatname_multiple(tmp2, sizeof(tmp2), line->cap), line->parent, line);
 			for (i = 0; i < MAX_SUBS; i++) {
 				sub = line->subs[i];
 				if (!sub)
@@ -5080,6 +5107,7 @@ static void finish_bookmark(void)
 	}
 }
 
+
 static struct unistim_device *build_device(const char *cat, const struct ast_variable *v)
 {
 	struct unistim_device *d;
@@ -5115,7 +5143,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
 		if (!(d = ast_calloc(1, sizeof(*d))))
 			return NULL;
 
-		if (!(l = ast_calloc(1, sizeof(*l)))) {
+		if (!(l = unistim_line_alloc())) {
 			ast_free(d);
 			return NULL;
 		}
@@ -5232,7 +5260,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
 						"You must use bookmark AFTER line=>. Only one line is supported in this version\n");
 				if (create) {
 					ast_free(d);
-					ast_free(l);
+					unistim_line_destroy(l);
 				}
 				return NULL;
 			}
@@ -5277,13 +5305,13 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
 					ast_verb(3, "Setting mailbox '%s' on %s@%s\n", l->mailbox, d->name, l->name);
 			}
 
-			l->capability = CAPABILITY;
+			ast_format_cap_copy(l->cap, global_cap);
 			l->parent = d;
 
 			if (create) {
 				if (!alloc_sub(l, SUB_REAL)) {
 					ast_mutex_destroy(&l->lock);
-					ast_free(l);
+					unistim_line_destroy(l);
 					ast_free(d);
 					return NULL;
 				}
@@ -5311,7 +5339,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
 	if (!d->lines) {
 		ast_log(LOG_ERROR, "An Unistim device must have at least one line!\n");
 		ast_mutex_destroy(&l->lock);
-		ast_free(l);
+		unistim_line_destroy(l);
 		if (d->tz) {
 			d->tz = ast_tone_zone_unref(d->tz);
 		}
@@ -5331,7 +5359,7 @@ static struct unistim_device *build_device(const char *cat, const struct ast_var
 		if (strcmp(d->name, "template")) {
 			ast_log(LOG_ERROR, "You must specify the mac address with device=\n");
 			ast_mutex_destroy(&l->lock);
-			ast_free(l);
+			unistim_line_destroy(l);
 			if (d->tz) {
 				d->tz = ast_tone_zone_unref(d->tz);
 			}
@@ -5635,7 +5663,17 @@ static struct ast_rtp_glue unistim_rtp_glue = {
 int load_module(void)
 {
 	int res;
+	struct ast_format tmpfmt;
+	if (!(global_cap = ast_format_cap_alloc())) {
+		goto buff_failed;
+	}
+	if (!(unistim_tech.capabilities = ast_format_cap_alloc())) {
+		goto buff_failed;
+	}
 
+	ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(global_cap, ast_format_set(&tmpfmt, AST_FORMAT_ALAW, 0));
+	ast_format_cap_copy(unistim_tech.capabilities, global_cap);
 	if (!(buff = ast_malloc(SIZE_PAGE)))
 		goto buff_failed;
 
@@ -5679,6 +5717,8 @@ sched_failed:
 io_failed:
 	ast_free(buff);
 	buff = NULL;
+	global_cap = ast_format_cap_destroy(global_cap);
+	unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
 buff_failed:
 	return AST_MODULE_LOAD_FAILURE;
 }
@@ -5709,6 +5749,9 @@ static int unload_module(void)
 	if (unistimsock > -1)
 		close(unistimsock);
 
+	global_cap = ast_format_cap_destroy(global_cap);
+	unistim_tech.capabilities = ast_format_cap_destroy(unistim_tech.capabilities);
+
 	return 0;
 }
 
diff --git a/channels/chan_usbradio.c b/channels/chan_usbradio.c
index eca7760ab196e8b5aedf1ab975f1d5d4522e4414..73995dd074b7478e3641dc2d980cd73cb3f5a009 100644
--- a/channels/chan_usbradio.c
+++ b/channels/chan_usbradio.c
@@ -661,7 +661,7 @@ static char *usbradio_active;	 /* the active device */
 
 static int setformat(struct chan_usbradio_pvt *o, int mode);
 
-static struct ast_channel *usbradio_request(const char *type, format_t format,
+static struct ast_channel *usbradio_request(const char *type, struct ast_format_cap *cap,
 		const struct ast_channel *requestor,
 		void *data, int *cause);
 static int usbradio_digit_begin(struct ast_channel *c, char digit);
@@ -682,10 +682,11 @@ static int RxTestIt(struct chan_usbradio_pvt *o);
 
 static char tdesc[] = "USB (CM108) Radio Channel Driver";
 
-static const struct ast_channel_tech usbradio_tech = {
+static struct ast_format slin;
+
+static struct ast_channel_tech usbradio_tech = {
 	.type = "Radio",
 	.description = tdesc,
-	.capabilities = AST_FORMAT_SLINEAR,
 	.requester = usbradio_request,
 	.send_digit_begin = usbradio_digit_begin,
 	.send_digit_end = usbradio_digit_end,
@@ -2060,7 +2061,7 @@ static struct ast_frame *usbradio_read(struct ast_channel *c)
 		return f;
 	/* ok we can build and deliver the frame to the caller */
 	f->frametype = AST_FRAME_VOICE;
-	f->subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&f->subclass.format, AST_FORMAT_SLINEAR, 0);
 	f->samples = FRAME_SIZE;
 	f->datalen = FRAME_SIZE * 2;
 	f->data.ptr = o->usbradio_read_buf_8k + AST_FRIENDLY_OFFSET;
@@ -2177,9 +2178,9 @@ static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext,
 	if (o->sounddev < 0)
 		setformat(o, O_RDWR);
 	c->fds[0] = o->sounddev;	/* -1 if device closed, override later */
-	c->nativeformats = AST_FORMAT_SLINEAR;
-	c->readformat = AST_FORMAT_SLINEAR;
-	c->writeformat = AST_FORMAT_SLINEAR;
+	ast_format_cap_add(c->nativeformats, &slin);
+	ast_format_set(&c->readformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&c->writeformat, AST_FORMAT_SLINEAR, 0);
 	c->tech_pvt = o;
 
 	if (!ast_strlen_zero(o->language))
@@ -2211,7 +2212,7 @@ static struct ast_channel *usbradio_new(struct chan_usbradio_pvt *o, char *ext,
 }
 /*
 */
-static struct ast_channel *usbradio_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+static struct ast_channel *usbradio_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct ast_channel *c;
 	struct chan_usbradio_pvt *o = find_desc(data);
@@ -2227,8 +2228,7 @@ static struct ast_channel *usbradio_request(const char *type, format_t format, c
 		/* XXX we could default to 'dsp' perhaps ? */
 		return NULL;
 	}
-	if ((format & AST_FORMAT_SLINEAR) == 0) {
-		ast_log(LOG_NOTICE, "Format 0x%" PRIx64 " unsupported\n", format);
+	if (!(ast_format_cap_iscompatible(cap, &slin))) {
 		return NULL;
 	}
 	if (o->owner) {
@@ -3932,6 +3932,11 @@ static int load_module(void)
 	struct ast_flags zeroflag = {0};
 #endif
 
+	if (!(usbradio_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(usbradio_tech.capabilities, ast_format_set(&slin, AST_FORMAT_SLINEAR, 0));
+
 	if (hid_device_mklist()) {
 		ast_log(LOG_NOTICE, "Unable to make hid list\n");
 		return AST_MODULE_LOAD_DECLINE;
@@ -4016,6 +4021,8 @@ static int unload_module(void)
 		/* XXX what about the thread ? */
 		/* XXX what about the memory allocated ? */
 	}
+
+	usbradio_tech.capabilities = ast_format_cap_destroy(usbradio_tech.capabilities);
 	return 0;
 }
 
diff --git a/channels/chan_vpb.cc b/channels/chan_vpb.cc
index 6a268bdb3239ea3dffb4eec5fa3c50b43c9b8e0d..0215ab82f5a4596973ff91e2e48144d52f37155a 100644
--- a/channels/chan_vpb.cc
+++ b/channels/chan_vpb.cc
@@ -101,8 +101,6 @@ static char language[MAX_LANGUAGE] = "";
 
 static int gruntdetect_timeout = 3600000; /* Grunt detect timeout is 1hr. */
 
-static const int prefformat = AST_FORMAT_SLINEAR;
-
 /* Protect the interface list (of vpb_pvt's) */
 AST_MUTEX_DEFINE_STATIC(iflock);
 
@@ -331,7 +329,7 @@ static struct vpb_pvt {
 
 static struct ast_channel *vpb_new(struct vpb_pvt *i, enum ast_channel_state state, const char *context, const char *linkedid);
 static void *do_chanreads(void *pvt);
-static struct ast_channel *vpb_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 static int vpb_digit_begin(struct ast_channel *ast, char digit);
 static int vpb_digit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static int vpb_call(struct ast_channel *ast, char *dest, int timeout);
@@ -346,7 +344,7 @@ static int vpb_fixup(struct ast_channel *oldchan, struct ast_channel *newchan);
 static struct ast_channel_tech vpb_tech = {
 	type: "vpb",
 	description: tdesc,
-	capabilities: AST_FORMAT_SLINEAR,
+	capabilities: NULL,
 	properties: 0,
 	requester: vpb_request,
 	devicestate: NULL,
@@ -380,7 +378,7 @@ static struct ast_channel_tech vpb_tech = {
 static struct ast_channel_tech vpb_tech_indicate = {
 	type: "vpb",
 	description: tdesc,
-	capabilities: AST_FORMAT_SLINEAR,
+	capabilities: NULL,
 	properties: 0,
 	requester: vpb_request,
 	devicestate: NULL,
@@ -755,10 +753,11 @@ static void get_callerid_ast(struct vpb_pvt *p)
 #endif
 		vpb_record_buf_start(p->handle, VPB_MULAW);
 		while ((rc == 0) && (sam_count < 8000 * 3)) {
+			struct ast_format tmpfmt;
 			vrc = vpb_record_buf_sync(p->handle, (char*)buf, sizeof(buf));
 			if (vrc != VPB_OK)
 				ast_log(LOG_ERROR, "%s: Caller ID couldn't read audio buffer!\n", p->dev);
-			rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), AST_FORMAT_ULAW);
+			rc = callerid_feed(cs, (unsigned char *)buf, sizeof(buf), ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0));
 #ifdef ANALYSE_CID
 			vpb_wave_write(ws, (char *)buf, sizeof(buf)); 
 #endif
@@ -2096,9 +2095,9 @@ static struct ast_frame *vpb_read(struct ast_channel *ast)
 	return &f;
 }
 
-static inline AudioCompress ast2vpbformat(format_t ast_format)
+static inline AudioCompress ast2vpbformat(struct ast_format *format)
 {
-	switch (ast_format) {
+	switch (format->id) {
 	case AST_FORMAT_ALAW:
 		return VPB_ALAW;
 	case AST_FORMAT_SLINEAR:
@@ -2112,9 +2111,9 @@ static inline AudioCompress ast2vpbformat(format_t ast_format)
 	}
 }
 
-static inline const char * ast2vpbformatname(format_t ast_format)
+static inline const char * ast2vpbformatname(struct ast_format *format)
 {
-	switch(ast_format) {
+	switch(format->id) {
 	case AST_FORMAT_ALAW:
 		return "AST_FORMAT_ALAW:VPB_ALAW";
 	case AST_FORMAT_SLINEAR:
@@ -2128,9 +2127,9 @@ static inline const char * ast2vpbformatname(format_t ast_format)
 	}
 }
 
-static inline int astformatbits(format_t ast_format)
+static inline int astformatbits(struct ast_format *format)
 {
-	switch (ast_format) {
+	switch (format->id) {
 	case AST_FORMAT_SLINEAR:
 		return 16;
 	case AST_FORMAT_ADPCM:
@@ -2174,7 +2173,7 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
 /*		ast_mutex_unlock(&p->lock); */
 		return 0;
 	} else if (ast->_state != AST_STATE_UP) {
-		ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n", ast->name, frame->frametype, ast_getformatname(frame->subclass.codec), ast->_state);
+		ast_verb(4, "%s: vpb_write: Attempt to Write frame type[%d]subclass[%s] on not up chan(state[%d])\n", ast->name, frame->frametype, ast_getformatname(&frame->subclass.format), ast->_state);
 		p->lastoutput = -1;
 /*		ast_mutex_unlock(&p->lock); */
 		return 0;
@@ -2182,9 +2181,9 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
 /*	ast_debug(1, "%s: vpb_write: Checked frame type..\n", p->dev); */
 
 
-	fmt = ast2vpbformat(frame->subclass.codec);
+	fmt = ast2vpbformat(&frame->subclass.format);
 	if (fmt < 0) {
-		ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast->name, ast_getformatname(frame->subclass.codec));
+		ast_log(LOG_WARNING, "%s: vpb_write: Cannot handle frames of %s format!\n", ast->name, ast_getformatname(&frame->subclass.format));
 		return -1;
 	}
 
@@ -2208,7 +2207,7 @@ static int vpb_write(struct ast_channel *ast, struct ast_frame *frame)
 	/* Check if we have set up the play_buf */
 	if (p->lastoutput == -1) {
 		vpb_play_buf_start(p->handle, fmt);
-		ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(frame->subclass.codec));
+		ast_verb(2, "%s: vpb_write: Starting play mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&frame->subclass.format));
 		p->lastoutput = fmt;
 		ast_mutex_unlock(&p->play_lock);
 		return 0;
@@ -2258,7 +2257,7 @@ static void *do_chanreads(void *pvt)
 	struct ast_frame *fr = &p->fr;
 	char *readbuf = ((char *)p->buf) + AST_FRIENDLY_OFFSET;
 	int bridgerec = 0;
-	format_t afmt;
+	struct ast_format tmpfmt;
 	int readlen, res, trycnt=0;
 	AudioCompress fmt;
 	int ignore_dtmf;
@@ -2353,26 +2352,23 @@ static void *do_chanreads(void *pvt)
 		}
 		ast_mutex_unlock(&p->play_dtmf_lock);
 
-/*		afmt = (p->owner) ? p->owner->rawreadformat : AST_FORMAT_SLINEAR; */
 		if (p->owner) {
-			afmt = p->owner->rawreadformat;
-/*			ast_debug(1,"%s: Record using owner format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
+			ast_format_copy(&tmpfmt, &p->owner->rawreadformat);
 		} else {
-			afmt = AST_FORMAT_SLINEAR;
-/*			ast_debug(1,"%s: Record using default format [%s]\n", p->dev, ast2vpbformatname(afmt)); */
+			ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0);
 		}
-		fmt = ast2vpbformat(afmt);
+		fmt = ast2vpbformat(&tmpfmt);
 		if (fmt < 0) {
-			ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_getformatname(afmt));
+			ast_log(LOG_WARNING, "%s: Record failure (unsupported format %s)\n", p->dev, ast_getformatname(&tmpfmt));
 			return NULL;
 		}
-		readlen = VPB_SAMPLES * astformatbits(afmt) / 8;
+		readlen = VPB_SAMPLES * astformatbits(&tmpfmt) / 8;
 
 		if (p->lastinput == -1) {
 			vpb_record_buf_start(p->handle, fmt);
 /*			vpb_reset_record_fifo_alarm(p->handle); */
 			p->lastinput = fmt;
-			ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(afmt));
+			ast_verb(2, "%s: Starting record mode (codec=%d)[%s]\n", p->dev, fmt, ast2vpbformatname(&tmpfmt));
 			continue;
 		} else if (p->lastinput != fmt) {
 			vpb_record_buf_finish(p->handle);
@@ -2391,7 +2387,7 @@ static void *do_chanreads(void *pvt)
 				a_gain_vector(p->rxswgain - MAX_VPB_GAIN, (short *)readbuf, readlen / sizeof(short));
 			ast_verb(6, "%s: chanreads: applied gain\n", p->dev);
 
-			fr->subclass.codec = afmt;
+			ast_format_copy(&fr->subclass.format, &tmpfmt);
 			fr->data.ptr = readbuf;
 			fr->datalen = readlen;
 			fr->frametype = AST_FRAME_VOICE;
@@ -2471,6 +2467,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
 	struct ast_channel *tmp; 
 	char cid_num[256];
 	char cid_name[256];
+	struct ast_format tmpfmt;
 
 	if (me->owner) {
 	    ast_log(LOG_WARNING, "Called vpb_new on owned channel (%s) ?!\n", me->dev);
@@ -2493,9 +2490,9 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
 		 * they are all converted to/from linear in the vpb code. Best for us to use
 		 * linear since we can then adjust volume in this modules.
 		 */
-		tmp->nativeformats = prefformat;
-		tmp->rawreadformat = AST_FORMAT_SLINEAR;
-		tmp->rawwriteformat =  AST_FORMAT_SLINEAR;
+		ast_format_cap_add(tmp->nativeformats, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+		ast_format_copy(&tmp->rawreadformat, &tmpfmt);
+		ast_format_copy(&tmp->rawwriteformat, &tmpfmt);
 		if (state == AST_STATE_RING) {
 			tmp->rings = 1;
 			cid_name[0] = '\0';
@@ -2541,19 +2538,20 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, enum ast_channel_state st
 	return tmp;
 }
 
-static struct ast_channel *vpb_request(const char *type, format_t format, const struct ast_channel *requestor, void *vdata, int *cause) 
+static struct ast_channel *vpb_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *vdata, int *cause) 
 {
-	format_t oldformat;
 	struct vpb_pvt *p;
 	struct ast_channel *tmp = NULL;
 	char *sepstr, *data = (char *)vdata, *name;
 	const char *s;
 	int group = -1;
+	struct ast_format slin;
+
+	ast_format_set(&slin, AST_FORMAT_SLINEAR, 0);
 
-	oldformat = format;
-	format &= prefformat;
-	if (!format) {
-		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname(oldformat));
+	if (!(ast_format_cap_iscompatible(cap, &slin))) {
+		char tmp[256];
+		ast_log(LOG_NOTICE, "Asked to get a channel of unsupported format '%s'\n", ast_getformatname_multiple(tmp, sizeof(tmp), cap));
 		return NULL;
 	}
 
@@ -2675,6 +2673,8 @@ static int unload_module(void)
 		ast_free(bridges);
 	}
 
+	ast_format_cap_destroy(vpb_tech.capabilities);
+	ast_format_cap_destroy(vpb_tech_indicate.capabilities);
 	return 0;
 }
 
@@ -2698,8 +2698,17 @@ static enum ast_module_load_result load_module()
 	int bal2 = -1; 
 	int bal3 = -1;
 	char * callerid = NULL;
-
+	struct ast_format tmpfmt;
 	int num_cards = 0;
+
+	if (!(vpb_tech.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	if (!(vpb_tech_indicate.capabilities = ast_format_cap_alloc())) {
+		return AST_MODULE_LOAD_DECLINE;
+	}
+	ast_format_cap_add(vpb_tech.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	ast_format_cap_add(vpb_tech_indicate.capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
 	try {
 		num_cards = vpb_get_num_cards();
 	} catch (std::exception e) {
diff --git a/channels/h323/ast_h323.cxx b/channels/h323/ast_h323.cxx
index c068389f8cab61b2a29e2525f6fc895bfc53c17b..b8f3aaaee20b06ed771ba793c5f88ab66f97215b 100644
--- a/channels/h323/ast_h323.cxx
+++ b/channels/h323/ast_h323.cxx
@@ -1770,20 +1770,21 @@ PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remo
 				if ((subType == codecs[x].h245_cap) && (!codecs[x].formatName || (!strcmp(codecs[x].formatName, (const char *)remoteCapabilities[i].GetFormatName())))) {
 					int ast_codec = codecs[x].asterisk_codec;
 					int ms = 0;
-					if (!(peer_capabilities & ast_codec)) {
+					struct ast_format tmpfmt;
+					if (!(peer_capabilities & ast_format_id_to_old_bitfield((enum ast_format_id) ast_codec))) {
 						struct ast_format_list format;
-						ast_codec_pref_append(&prefs, ast_codec);
-						format = ast_codec_pref_getsize(&prefs, ast_codec);
+						ast_codec_pref_append(&prefs, ast_format_set(&tmpfmt, (enum ast_format_id) ast_codec, 0));
+						format = ast_codec_pref_getsize(&prefs, &tmpfmt);
 						if ((ast_codec == AST_FORMAT_ALAW) || (ast_codec == AST_FORMAT_ULAW)) {
 							ms = remoteCapabilities[i].GetTxFramesInPacket();
 						} else
 							ms = remoteCapabilities[i].GetTxFramesInPacket() * format.inc_ms;
-						ast_codec_pref_setsize(&prefs, ast_codec, ms);
+						ast_codec_pref_setsize(&prefs, &tmpfmt, ms);
 					}
 					if (h323debug) {
 						cout << "Found peer capability " << remoteCapabilities[i] << ", Asterisk code is " << ast_codec << ", frame size (in ms) is " << ms << endl;
 					}
-					peer_capabilities |= ast_codec;
+					peer_capabilities |= ast_format_id_to_old_bitfield((enum ast_format_id) ast_codec);
 				}
 			}
 			break;
@@ -1846,12 +1847,7 @@ PBoolean MyH323Connection::OnReceivedCapabilitySet(const H323Capabilities & remo
 			break;
 		}
 	}
-	if (h323debug) {
-		char caps_str[1024], caps2_str[1024];
-		ast_codec_pref_string(&prefs, caps2_str, sizeof(caps2_str));
-		cout << "Peer capabilities = " << ast_getformatname_multiple(caps_str, sizeof(caps_str), peer_capabilities)
-				<< ", ordered list is " << caps2_str << endl;
-	}
+
 #if 0
 	redir_capabilities &= peer_capabilities;
 #endif
@@ -1897,38 +1893,37 @@ void MyH323Connection::SetCapabilities(int caps, int dtmf_mode, void *_prefs, in
 	int alreadysent = 0;
 	int codec;
 	int x, y;
-	char caps_str[1024];
 	struct ast_codec_pref *prefs = (struct ast_codec_pref *)_prefs;
 	struct ast_format_list format;
 	int frames_per_packet;
+	struct ast_format tmpfmt;
 	H323Capability *cap;
 
 	localCapabilities.RemoveAll();
 
-	if (h323debug) {
-		cout << "Setting capabilities to " << ast_getformatname_multiple(caps_str, sizeof(caps_str), caps) << endl;
-		ast_codec_pref_string(prefs, caps_str, sizeof(caps_str));
-		cout << "Capabilities in preference order is " << caps_str << endl;
-	}
 	/* Add audio codecs in preference order first, then
 	   audio codecs without preference as allowed by mask */
 	for (y = 0, x = -1; x < 32 + 32; ++x) {
+		ast_format_clear(&tmpfmt);
 		if (x < 0)
 			codec = pref_codec;
-		else if (y || (!(codec = ast_codec_pref_index(prefs, x)))) {
+		else if (y || (!(ast_codec_pref_index(prefs, x, &tmpfmt)))) {
 			if (!y)
 				y = 1;
 			else
 				y <<= 1;
 			codec = y;
 		}
-		if (!(caps & codec) || (alreadysent & codec) || !(codec & AST_FORMAT_AUDIO_MASK))
+		if (tmpfmt.id) {
+			codec = ast_format_to_old_bitfield(&tmpfmt);
+		}
+		if (!(caps & codec) || (alreadysent & codec) || (AST_FORMAT_GET_TYPE(ast_format_id_from_old_bitfield(codec)) != AST_FORMAT_TYPE_AUDIO))
 			continue;
 		alreadysent |= codec;
 		/* format.cur_ms will be set to default if packetization is not explicitly set */
-		format = ast_codec_pref_getsize(prefs, codec);
+		format = ast_codec_pref_getsize(prefs, ast_format_from_old_bitfield(&tmpfmt, codec));
 		frames_per_packet = (format.inc_ms ? format.cur_ms / format.inc_ms : format.cur_ms);
-		switch(codec) {
+		switch(ast_format_id_from_old_bitfield(codec)) {
 #if 0
 		case AST_FORMAT_SPEEX:
 			/* Not real sure if Asterisk acutally supports all
diff --git a/channels/h323/chan_h323.h b/channels/h323/chan_h323.h
index 2ae2c84c49835831d5c77e618f3b6336345b2915..ddabb669ac088cf47de8f183a1a9cc35cd6a5a9c 100644
--- a/channels/h323/chan_h323.h
+++ b/channels/h323/chan_h323.h
@@ -30,7 +30,7 @@
 #define CHAN_H323_H
 
 #include <arpa/inet.h>
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
 
 /*
  * Enable support for sending/reception of tunnelled Q.SIG messages and
@@ -47,6 +47,8 @@
 #define H323_HOLD_Q931ONLY	(1 << 1)
 #define H323_HOLD_H450		(1 << 2)
 
+typedef int64_t h323_format;
+
 /** call_option struct holds various bits
  *         of information for each call */
 typedef struct call_options {
@@ -65,7 +67,7 @@ typedef struct call_options {
 	int				progress_audio;
 	int				dtmfcodec[2];
 	int				dtmfmode;
-	format_t        capability;
+	h323_format     capability;
 	int				bridge;
 	int				nat;
 	int				tunnelOptions;
diff --git a/channels/iax2-parser.c b/channels/iax2-parser.c
index 094651e7097d3a412e328d7afdc68498b0efb4d9..ce9af244d8ca158a4937cfa6fd7d7ae17ee42dfc 100644
--- a/channels/iax2-parser.c
+++ b/channels/iax2-parser.c
@@ -218,9 +218,9 @@ static void dump_versioned_codec(char *output, int maxlen, void *value, int len)
 {
 	char *version = (char *) value;
 	if (version[0] == 0) {
-		if (len == (int) (sizeof(format_t) + sizeof(char))) {
-			format_t codec = ntohll(get_unaligned_uint64(value + 1));
-			ast_copy_string(output, ast_getformatname(codec), maxlen);
+		if (len == (int) (sizeof(iax2_format) + sizeof(char))) {
+			iax2_format codec = ntohll(get_unaligned_uint64(value + 1));
+			ast_copy_string(output, iax2_getformatname(codec), maxlen);
 		} else {
 			ast_copy_string(output, "Invalid length!", maxlen);
 		}
@@ -804,11 +804,11 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 			{
 				int version = data[2];
 				if (version == 0) {
-					if (len != (int)sizeof(char) + sizeof(format_t)) {
-						snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
+					if (len != (int)sizeof(char) + sizeof(iax2_format)) {
+						snprintf(tmp, (int)sizeof(tmp), "Expecting capability to be %d bytes long but was %d\n", (int) (sizeof(iax2_format) + sizeof(char)), len);
 						errorf(tmp);
 					} else {
-						ies->capability = (format_t) ntohll(get_unaligned_uint64(data + 3));
+						ies->capability = (iax2_format) ntohll(get_unaligned_uint64(data + 3));
 					}
 				} /* else unknown version */
 			}
@@ -825,11 +825,11 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 			{
 				int version = data[2];
 				if (version == 0) {
-					if (len != (int)sizeof(char) + sizeof(format_t)) {
-						snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(format_t) + sizeof(char)), len);
+					if (len != (int)sizeof(char) + sizeof(iax2_format)) {
+						snprintf(tmp, (int)sizeof(tmp), "Expecting format to be %d bytes long but was %d\n", (int) (sizeof(iax2_format) + sizeof(char)), len);
 						errorf(tmp);
 					} else {
-						ies->format = (format_t) ntohll(get_unaligned_uint64(data + 3));
+						ies->format = (iax2_format) ntohll(get_unaligned_uint64(data + 3));
 					}
 				} /* else unknown version */
 			}
@@ -1138,7 +1138,7 @@ int iax_parse_ies(struct iax_ies *ies, unsigned char *data, int datalen)
 void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
 {
 	fr->af.frametype = f->frametype;
-	fr->af.subclass.codec = f->subclass.codec;
+	ast_format_copy(&fr->af.subclass.format, &f->subclass.format);
 	fr->af.mallocd = 0;				/* Our frame is static relative to the container */
 	fr->af.datalen = f->datalen;
 	fr->af.samples = f->samples;
@@ -1157,7 +1157,7 @@ void iax_frame_wrap(struct iax_frame *fr, struct ast_frame *f)
 		}
 #if __BYTE_ORDER == __LITTLE_ENDIAN
 		/* We need to byte-swap slinear samples from network byte order */
-		if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.codec == AST_FORMAT_SLINEAR)) {
+		if ((fr->af.frametype == AST_FRAME_VOICE) && (fr->af.subclass.format.id == AST_FORMAT_SLINEAR)) {
 			/* 2 bytes / sample for SLINEAR */
 			ast_swapcopy_samples(fr->af.data.ptr, f->data.ptr, copy_len / 2);
 		} else
diff --git a/channels/iax2-parser.h b/channels/iax2-parser.h
index f25aaa3b7ade0b32de2f8bbff619a652abe420e0..978ca0d2a43247a493152bd27071961483bb1fc2 100644
--- a/channels/iax2-parser.h
+++ b/channels/iax2-parser.h
@@ -20,7 +20,7 @@
 
 #include "asterisk/linkedlists.h"
 #include "asterisk/crypto.h"
-#include "asterisk/frame_defs.h"
+#include "iax2.h"
 
 struct iax_ies {
 	char *called_number;
@@ -33,8 +33,8 @@ struct iax_ies {
 	char *called_context;
 	char *username;
 	char *password;
-	format_t capability;
-	format_t format;
+	iax2_format capability;
+	iax2_format format;
 	char *codec_prefs;
 	char *language;
 	int version;
diff --git a/channels/iax2-provision.c b/channels/iax2-provision.c
index c7af9f324e8abfbc8b5c3c68c5e0d849e61b622e..a95098236c167844d03776d6b80133ce1dc4969d 100644
--- a/channels/iax2-provision.c
+++ b/channels/iax2-provision.c
@@ -59,7 +59,7 @@ struct iax_template {
 	unsigned short serverport;
 	unsigned int altserver;
 	unsigned int flags;
-	unsigned int format;
+	iax2_format format;
 	unsigned int tos;
 	AST_LIST_ENTRY(iax_template) list;
 };
@@ -340,8 +340,9 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg,
 			} else 
 				ast_log(LOG_WARNING, "Ignoring invalid %s '%s' for '%s' at line %d\n", v->name, v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "codec")) {
-			if ((x = ast_getformatbyname(v->value)) > 0) {
-				cur->format = x;
+			struct ast_format tmpfmt;
+			if ((ast_getformatbyname(v->value, &tmpfmt)) > 0) {
+				cur->format = ast_format_to_old_bitfield(&tmpfmt);
 			} else
 				ast_log(LOG_WARNING, "Ignoring invalid codec '%s' for '%s' at line %d\n", v->value, s, v->lineno);
 		} else if (!strcasecmp(v->name, "tos")) {
@@ -468,7 +469,7 @@ static char *iax_show_provisioning(struct ast_cli_entry *e, int cmd, struct ast_
 			ast_cli(a->fd, "Server Port:  %d\n", cur->serverport);
 			ast_cli(a->fd, "Alternate:    %s\n", alternate);
 			ast_cli(a->fd, "Flags:        %s\n", iax_provflags2str(flags, sizeof(flags), cur->flags));
-			ast_cli(a->fd, "Format:       %s\n", ast_getformatname(cur->format));
+			ast_cli(a->fd, "Format:       %s\n", iax2_getformatname(cur->format));
 			ast_cli(a->fd, "TOS:          0x%x\n", cur->tos);
 			found++;
 		}
diff --git a/channels/iax2.h b/channels/iax2.h
index 825efb8cb28409a19d07e06639fafffed8508993..d579ed8aad7b8174e53e7aa6bd4e18a12ddf9c9b 100644
--- a/channels/iax2.h
+++ b/channels/iax2.h
@@ -214,6 +214,12 @@ enum iax_frame_subclass {
 #define IAX_DPSTATUS_IGNOREPAT		(1 << 14)
 #define IAX_DPSTATUS_MATCHMORE		(1 << 15)
 
+/*! iax2 format bit field for handling codecs the old way */
+typedef int64_t iax2_format;
+
+/*!\brief iax2 wrapper function for ast_getformatname */
+char *iax2_getformatname(iax2_format format);
+
 /*! Full frames are always delivered reliably */
 struct ast_iax2_full_hdr {
 	unsigned short scallno;	/*!< Source call number -- high bit must be 1 */
diff --git a/channels/sip/include/globals.h b/channels/sip/include/globals.h
index 0bd2f4d2d1c8315ea29b1c3cd81283e33702434a..d7c9f13d0893f093eb31a9083fa7543696aad64e 100644
--- a/channels/sip/include/globals.h
+++ b/channels/sip/include/globals.h
@@ -28,7 +28,7 @@ extern struct ast_sockaddr bindaddr;     /*!< UDP: The address we bind to */
 extern struct ast_sched_context *sched;     /*!< The scheduling context */
 
 /*! \brief Definition of this channel for PBX channel registration */
-extern const struct ast_channel_tech sip_tech;
+extern struct ast_channel_tech sip_tech;
 
 /*! \brief This version of the sip channel tech has no send_digit_begin
  * callback so that the core knows that the channel does not want
diff --git a/channels/sip/include/sip.h b/channels/sip/include/sip.h
index 57c155e141c42e0337a5cac37ceee8b2d7151a91..e5d8205e58644228638476c89b92865e4d154649 100644
--- a/channels/sip/include/sip.h
+++ b/channels/sip/include/sip.h
@@ -216,7 +216,6 @@
 #define DEFAULT_SDPSESSION "Asterisk PBX"  /*!< Default SDP session name, (s=) header unless re-defined in sip.conf */
 #define DEFAULT_SDPOWNER   "root"          /*!< Default SDP username field in (o=) header unless re-defined in sip.conf */
 #define DEFAULT_ENGINE     "asterisk"      /*!< Default RTP engine to use for sessions */
-#define DEFAULT_CAPABILITY (AST_FORMAT_ULAW | AST_FORMAT_TESTLAW | AST_FORMAT_ALAW | AST_FORMAT_GSM | AST_FORMAT_H263);
 #endif
 /*@}*/
 
@@ -695,7 +694,7 @@ struct sip_settings {
 	char default_context[AST_MAX_CONTEXT];
 	char default_subscribecontext[AST_MAX_CONTEXT];
 	struct ast_ha *contact_ha;  /*! \brief Global list of addresses dynamic peers are not allowed to use */
-	format_t capability;        /*!< Supported codecs */
+	struct ast_format_cap *caps; /*!< Supported codecs */
 	int tcp_enabled;
 	int default_max_forwards;    /*!< Default max forwards (SIP Anti-loop) */
 };
@@ -995,13 +994,13 @@ struct sip_pvt {
 	unsigned int sipoptions;          /*!< Supported SIP options on the other end */
 	unsigned int reqsipoptions;       /*!< Required SIP options on the other end */
 	struct ast_codec_pref prefs;      /*!< codec prefs */
-	format_t capability;              /*!< Special capability (codec) */
-	format_t jointcapability;         /*!< Supported capability at both ends (codecs) */
-	format_t peercapability;          /*!< Supported peer capability */
-	format_t prefcodec;               /*!< Preferred codec (outbound only) */
+	struct ast_format_cap *caps;             /*!< Special capability (codec) */
+	struct ast_format_cap *jointcaps;        /*!< Supported capability at both ends (codecs) */
+	struct ast_format_cap *peercaps;         /*!< Supported peer capability */
+	struct ast_format_cap *redircaps;        /*!< Redirect codecs */
+	struct ast_format_cap *prefcaps;         /*!< Preferred codec (outbound only) */
 	int noncodeccapability;	          /*!< DTMF RFC2833 telephony-event */
 	int jointnoncodeccapability;      /*!< Joint Non codec capability */
-	format_t redircodecs;             /*!< Redirect codecs */
 	int maxcallbitrate;               /*!< Maximum Call Bitrate for Video Calls */	
 	int t38_maxdatagram;              /*!< T.38 FaxMaxDatagram override */
 	int request_queue_sched_id;       /*!< Scheduler ID of any scheduled action to process queued requests */
@@ -1217,7 +1216,7 @@ struct sip_peer {
 
 	int maxcallbitrate;             /*!<  Maximum Bitrate for a video call */
 	int expire;                     /*!<  When to expire this peer registration */
-	format_t capability;            /*!<  Codec capability */
+	struct ast_format_cap *caps;            /*!<  Codec capability */
 	int rtptimeout;                 /*!<  RTP timeout */
 	int rtpholdtimeout;             /*!<  RTP Hold Timeout */
 	int rtpkeepalive;               /*!<  Send RTP packets for keepalive */
diff --git a/codecs/codec_a_mu.c b/codecs/codec_a_mu.c
index 9b2e408500e8fa4b6f583f5877a61ad78ca5b42e..a7d86e2c4cc7fd7ff698af2ddca047e03c28fb53 100644
--- a/codecs/codec_a_mu.c
+++ b/codecs/codec_a_mu.c
@@ -76,8 +76,6 @@ static int ulawtoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 
 static struct ast_translator alawtoulaw = {
 	.name = "alawtoulaw",
-	.srcfmt = AST_FORMAT_ALAW,
-	.dstfmt = AST_FORMAT_ULAW,
 	.framein = alawtoulaw_framein,
 	.sample = alaw_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -86,8 +84,6 @@ static struct ast_translator alawtoulaw = {
 
 static struct ast_translator ulawtoalaw = {
 	.name = "ulawtoalaw",
-	.srcfmt = AST_FORMAT_ULAW,
-	.dstfmt = AST_FORMAT_ALAW,
 	.framein = ulawtoalaw_framein,
 	.sample = ulaw_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -111,6 +107,12 @@ static int load_module(void)
 	int res;
 	int x;
 
+	ast_format_set(&alawtoulaw.src_format, AST_FORMAT_ALAW, 0);
+	ast_format_set(&alawtoulaw.dst_format, AST_FORMAT_ULAW, 0);
+
+	ast_format_set(&ulawtoalaw.src_format, AST_FORMAT_ULAW, 0);
+	ast_format_set(&ulawtoalaw.dst_format, AST_FORMAT_ALAW, 0);
+
 	for (x=0;x<256;x++) {
 		mu2a[x] = AST_LIN2A(AST_MULAW(x));
 		a2mu[x] = AST_LIN2MU(AST_ALAW(x));
diff --git a/codecs/codec_adpcm.c b/codecs/codec_adpcm.c
index a1b0680a518a8ff073cf762833e2121234ecfca0..63745c17041927481111e4ddd887cbef8493159f 100644
--- a/codecs/codec_adpcm.c
+++ b/codecs/codec_adpcm.c
@@ -286,8 +286,6 @@ static struct ast_frame *lintoadpcm_frameout(struct ast_trans_pvt *pvt)
 
 static struct ast_translator adpcmtolin = {
 	.name = "adpcmtolin",
-	.srcfmt = AST_FORMAT_ADPCM,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.framein = adpcmtolin_framein,
 	.sample = adpcm_sample,
 	.desc_size = sizeof(struct adpcm_decoder_pvt),
@@ -297,8 +295,6 @@ static struct ast_translator adpcmtolin = {
 
 static struct ast_translator lintoadpcm = {
 	.name = "lintoadpcm",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_ADPCM,
 	.framein = lintoadpcm_framein,
 	.frameout = lintoadpcm_frameout,
 	.sample = slin8_sample,
@@ -327,6 +323,12 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&adpcmtolin.src_format, AST_FORMAT_ADPCM, 0);
+	ast_format_set(&adpcmtolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintoadpcm.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintoadpcm.dst_format, AST_FORMAT_ADPCM, 0);
+
 	res = ast_register_translator(&adpcmtolin);
 	if (!res)
 		res = ast_register_translator(&lintoadpcm);
diff --git a/codecs/codec_alaw.c b/codecs/codec_alaw.c
index bb749d003f43d03b065839430390ff5a0abfeb6c..3d2fc92aec3871f8d7f2041853a9767a5773a293 100644
--- a/codecs/codec_alaw.c
+++ b/codecs/codec_alaw.c
@@ -73,8 +73,6 @@ static int lintoalaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 
 static struct ast_translator alawtolin = {
 	.name = "alawtolin",
-	.srcfmt = AST_FORMAT_ALAW,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.framein = alawtolin_framein,
 	.sample = alaw_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -83,8 +81,6 @@ static struct ast_translator alawtolin = {
 
 static struct ast_translator lintoalaw = {
 	"lintoalaw",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_ALAW,
 	.framein = lintoalaw_framein,
 	.sample = slin8_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -112,6 +108,12 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&lintoalaw.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintoalaw.dst_format, AST_FORMAT_ALAW, 0);
+
+	ast_format_set(&alawtolin.src_format, AST_FORMAT_ALAW, 0);
+	ast_format_set(&alawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
 	res = ast_register_translator(&alawtolin);
 	if (!res)
 		res = ast_register_translator(&lintoalaw);
diff --git a/codecs/codec_dahdi.c b/codecs/codec_dahdi.c
index 64b73cdc1001e78055afdff85bce50815f94d418..960a594f7884ba08075865137dc3d118b30399e1 100644
--- a/codecs/codec_dahdi.c
+++ b/codecs/codec_dahdi.c
@@ -179,7 +179,7 @@ static int dahdi_encoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 {
 	struct codec_dahdi_pvt *dahdip = pvt->pvt;
 
-	if (!f->subclass.codec) {
+	if (!f->subclass.format.id) {
 		/* We're just faking a return for calculation purposes. */
 		dahdip->fake = 2;
 		pvt->samples = f->samples;
@@ -227,7 +227,7 @@ static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
 	if (2 == dahdip->fake) {
 		dahdip->fake = 1;
 		pvt->f.frametype = AST_FRAME_VOICE;
-		pvt->f.subclass.codec = 0;
+		ast_format_clear(&pvt->f.subclass.format);
 		pvt->f.samples = dahdip->required_samples;
 		pvt->f.data.ptr = NULL;
 		pvt->f.offset = 0;
@@ -255,7 +255,7 @@ static struct ast_frame *dahdi_encoder_frameout(struct ast_trans_pvt *pvt)
 		pvt->f.datalen = res;
 		pvt->f.samples = dahdip->required_samples;
 		pvt->f.frametype = AST_FRAME_VOICE;
-		pvt->f.subclass.codec = 1 <<  (pvt->t->dstfmt);
+		ast_format_copy(&pvt->f.subclass.format, &pvt->t->dst_format);
 		pvt->f.mallocd = 0;
 		pvt->f.offset = AST_FRIENDLY_OFFSET;
 		pvt->f.src = pvt->t->name;
@@ -274,7 +274,7 @@ static int dahdi_decoder_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 {
 	struct codec_dahdi_pvt *dahdip = pvt->pvt;
 
-	if (!f->subclass.codec) {
+	if (!f->subclass.format.id) {
 		/* We're just faking a return for calculation purposes. */
 		dahdip->fake = 2;
 		pvt->samples = f->samples;
@@ -300,7 +300,7 @@ static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
 	if (2 == dahdip->fake) {
 		dahdip->fake = 1;
 		pvt->f.frametype = AST_FRAME_VOICE;
-		pvt->f.subclass.codec = 0;
+		ast_format_clear(&pvt->f.subclass.format);
 		pvt->f.samples = dahdip->required_samples;
 		pvt->f.data.ptr = NULL;
 		pvt->f.offset = 0;
@@ -338,7 +338,7 @@ static struct ast_frame *dahdi_decoder_frameout(struct ast_trans_pvt *pvt)
 		}
 		pvt->datalen = 0;
 		pvt->f.frametype = AST_FRAME_VOICE;
-		pvt->f.subclass.codec = 1 <<  (pvt->t->dstfmt);
+		ast_format_copy(&pvt->f.subclass.format, &pvt->t->dst_format);
 		pvt->f.mallocd = 0;
 		pvt->f.offset = AST_FRIENDLY_OFFSET;
 		pvt->f.src = pvt->t->name;
@@ -371,7 +371,7 @@ static void dahdi_destroy(struct ast_trans_pvt *pvt)
 	close(dahdip->fd);
 }
 
-static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
+static int dahdi_translate(struct ast_trans_pvt *pvt, struct ast_format *dst_format, struct ast_format *src_format)
 {
 	/* Request translation through zap if possible */
 	int fd;
@@ -385,10 +385,10 @@ static int dahdi_translate(struct ast_trans_pvt *pvt, int dest, int source)
 		return -1;
 	}
 
-	dahdip->fmts.srcfmt = (1 << source);
-	dahdip->fmts.dstfmt = (1 << dest);
+	dahdip->fmts.srcfmt = ast_format_to_old_bitfield(src_format);
+	dahdip->fmts.dstfmt = ast_format_to_old_bitfield(dst_format);
 
-	ast_debug(1, "Opening transcoder channel from %d to %d.\n", source, dest);
+	ast_debug(1, "Opening transcoder channel from %s to %s.\n", ast_getformatname(src_format), ast_getformatname(dst_format));
 
 retry:
 	if (ioctl(fd, DAHDI_TC_ALLOCATE, &dahdip->fmts)) {
@@ -401,14 +401,14 @@ retry:
 			 * support for ULAW instead of signed linear and then
 			 * we'll just convert from ulaw to signed linear in
 			 * software. */
-			if (AST_FORMAT_SLINEAR == dahdip->fmts.srcfmt) {
+			if (AST_FORMAT_SLINEAR == ast_format_id_from_old_bitfield(dahdip->fmts.srcfmt)) {
 				ast_debug(1, "Using soft_slin support on source\n");
 				dahdip->softslin = 1;
-				dahdip->fmts.srcfmt = AST_FORMAT_ULAW;
-			} else if (AST_FORMAT_SLINEAR == dahdip->fmts.dstfmt) {
+				dahdip->fmts.srcfmt = ast_format_id_to_old_bitfield(AST_FORMAT_ULAW);
+			} else if (AST_FORMAT_SLINEAR == ast_format_id_from_old_bitfield(dahdip->fmts.dstfmt)) {
 				ast_debug(1, "Using soft_slin support on destination\n");
 				dahdip->softslin = 1;
-				dahdip->fmts.dstfmt = AST_FORMAT_ULAW;
+				dahdip->fmts.dstfmt = ast_format_id_to_old_bitfield(AST_FORMAT_ULAW);
 			}
 			tried_once = 1;
 			goto retry;
@@ -427,9 +427,9 @@ retry:
 
 	dahdip->fd = fd;
 
-	dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt)&AST_FORMAT_G723_1) ? G723_SAMPLES : G729_SAMPLES;
+	dahdip->required_samples = ((dahdip->fmts.dstfmt|dahdip->fmts.srcfmt) & (ast_format_id_to_old_bitfield(AST_FORMAT_G723_1))) ? G723_SAMPLES : G729_SAMPLES;
 
-	switch (dahdip->fmts.dstfmt) {
+	switch (ast_format_id_from_old_bitfield(dahdip->fmts.dstfmt)) {
 	case AST_FORMAT_G729A:
 		ast_atomic_fetchadd_int(&channels.encoders, +1);
 		break;
@@ -446,7 +446,9 @@ retry:
 
 static int dahdi_new(struct ast_trans_pvt *pvt)
 {
-	return dahdi_translate(pvt, pvt->t->dstfmt, pvt->t->srcfmt);
+	return dahdi_translate(pvt,
+		&pvt->t->dst_format,
+		&pvt->t->src_format);
 }
 
 static struct ast_frame *fakesrc_sample(void)
@@ -463,7 +465,9 @@ static struct ast_frame *fakesrc_sample(void)
 
 static int is_encoder(struct translator *zt)
 {
-	if (zt->t.srcfmt&(AST_FORMAT_ULAW|AST_FORMAT_ALAW|AST_FORMAT_SLINEAR)) {
+	if ((zt->t.src_format.id == AST_FORMAT_ULAW) ||
+		(zt->t.src_format.id == AST_FORMAT_ALAW) ||
+		(zt->t.src_format.id == AST_FORMAT_SLINEAR)) {
 		return 1;
 	} else {
 		return 0;
@@ -474,15 +478,20 @@ static int register_translator(int dst, int src)
 {
 	struct translator *zt;
 	int res;
+	struct ast_format dst_format;
+	struct ast_format src_format;
+
+	ast_format_from_old_bitfield(&dst_format, (1 << dst));
+	ast_format_from_old_bitfield(&src_format, (1 << src));
 
 	if (!(zt = ast_calloc(1, sizeof(*zt)))) {
 		return -1;
 	}
 
 	snprintf((char *) (zt->t.name), sizeof(zt->t.name), "zap%sto%s",
-		 ast_getformatname((1 << src)), ast_getformatname((1 << dst)));
-	zt->t.srcfmt = (1 << src);
-	zt->t.dstfmt = (1 << dst);
+		 ast_getformatname(&src_format), ast_getformatname(&dst_format));
+	ast_format_copy(&zt->t.src_format, &src_format);
+	ast_format_copy(&zt->t.dst_format, &dst_format);
 	zt->t.buf_size = BUFFER_SIZE;
 	if (is_encoder(zt)) {
 		zt->t.framein = dahdi_encoder_framein;
@@ -518,10 +527,10 @@ static void drop_translator(int dst, int src)
 
 	AST_LIST_LOCK(&translators);
 	AST_LIST_TRAVERSE_SAFE_BEGIN(&translators, cur, entry) {
-		if (cur->t.srcfmt != src)
+		if (cur->t.src_format.id != ast_format_id_from_old_bitfield((1 << src)))
 			continue;
 
-		if (cur->t.dstfmt != dst)
+		if (cur->t.dst_format.id != ast_format_id_from_old_bitfield((1 << dst)))
 			continue;
 
 		AST_LIST_REMOVE_CURRENT(entry);
diff --git a/codecs/codec_g722.c b/codecs/codec_g722.c
index 22196da011114e58785ba8250e6222a46a2c35bc..9c3a018468280b5e0a144464509c3b0145d7d95a 100644
--- a/codecs/codec_g722.c
+++ b/codecs/codec_g722.c
@@ -134,8 +134,6 @@ static int lintog722_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 
 static struct ast_translator g722tolin = {
 	.name = "g722tolin",
-	.srcfmt = AST_FORMAT_G722,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = g722tolin_new,	/* same for both directions */
 	.framein = g722tolin_framein,
 	.sample = g722_sample,
@@ -146,8 +144,6 @@ static struct ast_translator g722tolin = {
 
 static struct ast_translator lintog722 = {
 	.name = "lintog722",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_G722,
 	.newpvt = lintog722_new,	/* same for both directions */
 	.framein = lintog722_framein,
 	.sample = slin8_sample,
@@ -158,8 +154,6 @@ static struct ast_translator lintog722 = {
 
 static struct ast_translator g722tolin16 = {
 	.name = "g722tolin16",
-	.srcfmt = AST_FORMAT_G722,
-	.dstfmt = AST_FORMAT_SLINEAR16,
 	.newpvt = g722tolin16_new,	/* same for both directions */
 	.framein = g722tolin_framein,
 	.sample = g722_sample,
@@ -170,8 +164,6 @@ static struct ast_translator g722tolin16 = {
 
 static struct ast_translator lin16tog722 = {
 	.name = "lin16tog722",
-	.srcfmt = AST_FORMAT_SLINEAR16,
-	.dstfmt = AST_FORMAT_G722,
 	.newpvt = lin16tog722_new,	/* same for both directions */
 	.framein = lintog722_framein,
 	.sample = slin16_sample,
@@ -201,6 +193,18 @@ static int load_module(void)
 {
 	int res = 0;
 
+	ast_format_set(&g722tolin.src_format, AST_FORMAT_G722, 0);
+	ast_format_set(&g722tolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintog722.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintog722.dst_format, AST_FORMAT_G722, 0);
+
+	ast_format_set(&g722tolin16.src_format, AST_FORMAT_G722, 0);
+	ast_format_set(&g722tolin16.dst_format, AST_FORMAT_SLINEAR16, 0);
+
+	ast_format_set(&lin16tog722.src_format, AST_FORMAT_SLINEAR16, 0);
+	ast_format_set(&lin16tog722.dst_format, AST_FORMAT_G722, 0);
+
 	res |= ast_register_translator(&g722tolin);
 	res |= ast_register_translator(&lintog722);
 	res |= ast_register_translator(&g722tolin16);
diff --git a/codecs/codec_g726.c b/codecs/codec_g726.c
index cc9b1cb31e5864a3d646640396ab6c80f13666e8..f8a57f740eb92d0a62b75929217874f581032e7c 100644
--- a/codecs/codec_g726.c
+++ b/codecs/codec_g726.c
@@ -771,8 +771,6 @@ static int lintog726_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 
 static struct ast_translator g726tolin = {
 	.name = "g726tolin",
-	.srcfmt = AST_FORMAT_G726,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = lintog726_new,	/* same for both directions */
 	.framein = g726tolin_framein,
 	.sample = g726_sample,
@@ -783,8 +781,6 @@ static struct ast_translator g726tolin = {
 
 static struct ast_translator lintog726 = {
 	.name = "lintog726",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_G726,
 	.newpvt = lintog726_new,	/* same for both directions */
 	.framein = lintog726_framein,
 	.sample = slin8_sample,
@@ -795,8 +791,6 @@ static struct ast_translator lintog726 = {
 
 static struct ast_translator g726aal2tolin = {
 	.name = "g726aal2tolin",
-	.srcfmt = AST_FORMAT_G726_AAL2,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = lintog726_new,	/* same for both directions */
 	.framein = g726aal2tolin_framein,
 	.sample = g726_sample,
@@ -807,8 +801,6 @@ static struct ast_translator g726aal2tolin = {
 
 static struct ast_translator lintog726aal2 = {
 	.name = "lintog726aal2",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_G726_AAL2,
 	.newpvt = lintog726_new,	/* same for both directions */
 	.framein = lintog726aal2_framein,
 	.sample = slin8_sample,
@@ -839,6 +831,18 @@ static int load_module(void)
 {
 	int res = 0;
 
+	ast_format_set(&g726tolin.src_format, AST_FORMAT_G726, 0);
+	ast_format_set(&g726tolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintog726.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintog726.dst_format, AST_FORMAT_G726, 0);
+
+	ast_format_set(&g726aal2tolin.src_format, AST_FORMAT_G726_AAL2, 0);
+	ast_format_set(&g726aal2tolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintog726aal2.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintog726aal2.dst_format, AST_FORMAT_G726_AAL2, 0);
+
 	res |= ast_register_translator(&g726tolin);
 	res |= ast_register_translator(&lintog726);
 
diff --git a/codecs/codec_gsm.c b/codecs/codec_gsm.c
index ab28154457aa86421cb83276a7d91346334e6f7c..46c1c84fb88c2ddd8d560b131f147eb2e8dc98b4 100644
--- a/codecs/codec_gsm.c
+++ b/codecs/codec_gsm.c
@@ -168,8 +168,6 @@ static void gsm_destroy_stuff(struct ast_trans_pvt *pvt)
 
 static struct ast_translator gsmtolin = {
 	.name = "gsmtolin", 
-	.srcfmt = AST_FORMAT_GSM,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = gsm_new,
 	.framein = gsmtolin_framein,
 	.destroy = gsm_destroy_stuff,
@@ -181,8 +179,6 @@ static struct ast_translator gsmtolin = {
 
 static struct ast_translator lintogsm = {
 	.name = "lintogsm", 
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_GSM,
 	.newpvt = gsm_new,
 	.framein = lintogsm_framein,
 	.frameout = lintogsm_frameout,
@@ -213,6 +209,12 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&gsmtolin.src_format, AST_FORMAT_GSM, 0);
+	ast_format_set(&gsmtolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintogsm.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintogsm.dst_format, AST_FORMAT_GSM, 0);
+
 	res = ast_register_translator(&gsmtolin);
 	if (!res) 
 		res=ast_register_translator(&lintogsm);
diff --git a/codecs/codec_ilbc.c b/codecs/codec_ilbc.c
index 3227dc80e34ef76b7f7eb0c88b023536207683b8..bbd0019deb94fecde78d11bb16c1690157e17365 100644
--- a/codecs/codec_ilbc.c
+++ b/codecs/codec_ilbc.c
@@ -166,8 +166,6 @@ static struct ast_frame *lintoilbc_frameout(struct ast_trans_pvt *pvt)
 
 static struct ast_translator ilbctolin = {
 	.name = "ilbctolin", 
-	.srcfmt = AST_FORMAT_ILBC,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = ilbctolin_new,
 	.framein = ilbctolin_framein,
 	.sample = ilbc_sample,
@@ -178,8 +176,6 @@ static struct ast_translator ilbctolin = {
 
 static struct ast_translator lintoilbc = {
 	.name = "lintoilbc", 
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_ILBC,
 	.newpvt = lintoilbc_new,
 	.framein = lintoilbc_framein,
 	.frameout = lintoilbc_frameout,
@@ -202,6 +198,13 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&ilibctolin.src_format, AST_FORMAT_ILBC, 0);
+	ast_format_set(&ilibctolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintoilbc.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintoilbc.dst_format, AST_FORMAT_ILBC, 0);
+
+
 	res = ast_register_translator(&ilbctolin);
 	if (!res) 
 		res=ast_register_translator(&lintoilbc);
diff --git a/codecs/codec_lpc10.c b/codecs/codec_lpc10.c
index d61729c9547248553197cd0e765d12b0c41738c2..7d1739203f42e410d8c1a36a3e71fa2d5e661201 100644
--- a/codecs/codec_lpc10.c
+++ b/codecs/codec_lpc10.c
@@ -193,8 +193,6 @@ static void lpc10_destroy(struct ast_trans_pvt *arg)
 
 static struct ast_translator lpc10tolin = {
 	.name = "lpc10tolin", 
-	.srcfmt = AST_FORMAT_LPC10,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = lpc10_dec_new,
 	.framein = lpc10tolin_framein,
 	.destroy = lpc10_destroy,
@@ -206,8 +204,6 @@ static struct ast_translator lpc10tolin = {
 
 static struct ast_translator lintolpc10 = {
 	.name = "lintolpc10", 
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_LPC10,
 	.newpvt = lpc10_enc_new,
 	.framein = lintolpc10_framein,
 	.frameout = lintolpc10_frameout,
@@ -238,6 +234,12 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&lpc10tolin.src_format, AST_FORMAT_LPC10, 0);
+	ast_format_set(&lpc10tolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintolpc10.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintolpc10.dst_format, AST_FORMAT_LPC10, 0);
+
 	res = ast_register_translator(&lpc10tolin);
 	if (!res) 
 		res = ast_register_translator(&lintolpc10);
diff --git a/codecs/codec_resample.c b/codecs/codec_resample.c
index 834fb46ba7c63c43eb1c17ff31353fc7ff83da66..80823bb7c8ecb911d2e44799fd48544876e74135 100644
--- a/codecs/codec_resample.c
+++ b/codecs/codec_resample.c
@@ -170,8 +170,6 @@ static int slin8_to_slin16_framein(struct ast_trans_pvt *pvt, struct ast_frame *
 
 static struct ast_translator slin16_to_slin8 = {
 	.name = "slin16_to_slin8",
-	.srcfmt = AST_FORMAT_SLINEAR16,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.newpvt = slin16_to_slin8_new,
 	.destroy = slin16_to_slin8_destroy,
 	.framein = slin16_to_slin8_framein,
@@ -183,8 +181,6 @@ static struct ast_translator slin16_to_slin8 = {
 
 static struct ast_translator slin8_to_slin16 = {
 	.name = "slin8_to_slin16",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_SLINEAR16,
 	.newpvt = slin8_to_slin16_new,
 	.destroy = slin8_to_slin16_destroy,
 	.framein = slin8_to_slin16_framein,
@@ -208,6 +204,12 @@ static int load_module(void)
 {
 	int res = 0;
 
+	ast_format_set(&slin16_to_slin8.src_format, AST_FORMAT_SLINEAR16, 0);
+	ast_format_set(&slin16_to_slin8.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&slin8_to_slin16.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&slin8_to_slin16.dst_format, AST_FORMAT_SLINEAR16, 0);
+
 	res |= ast_register_translator(&slin16_to_slin8);
 	res |= ast_register_translator(&slin8_to_slin16);
 
diff --git a/codecs/codec_speex.c b/codecs/codec_speex.c
index 2bfdec228163675e26c32c936744116b01030f29..aaaa1bea25d72cfaf629306d3fec6fe079288e4b 100644
--- a/codecs/codec_speex.c
+++ b/codecs/codec_speex.c
@@ -330,8 +330,6 @@ static void lintospeex_destroy(struct ast_trans_pvt *arg)
 
 static struct ast_translator speextolin = {
 	.name = "speextolin", 
-	.srcfmt = AST_FORMAT_SPEEX,
-	.dstfmt =  AST_FORMAT_SLINEAR,
 	.newpvt = speextolin_new,
 	.framein = speextolin_framein,
 	.destroy = speextolin_destroy,
@@ -344,8 +342,6 @@ static struct ast_translator speextolin = {
 
 static struct ast_translator lintospeex = {
 	.name = "lintospeex", 
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_SPEEX,
 	.newpvt = lintospeex_new,
 	.framein = lintospeex_framein,
 	.frameout = lintospeex_frameout,
@@ -358,8 +354,6 @@ static struct ast_translator lintospeex = {
 
 static struct ast_translator speexwbtolin16 = {
 	.name = "speexwbtolin16", 
-	.srcfmt = AST_FORMAT_SPEEX16,
-	.dstfmt =  AST_FORMAT_SLINEAR16,
 	.newpvt = speexwbtolin16_new,
 	.framein = speextolin_framein,
 	.destroy = speextolin_destroy,
@@ -372,8 +366,6 @@ static struct ast_translator speexwbtolin16 = {
 
 static struct ast_translator lin16tospeexwb = {
 	.name = "lin16tospeexwb", 
-	.srcfmt = AST_FORMAT_SLINEAR16,
-	.dstfmt = AST_FORMAT_SPEEX16,
 	.newpvt = lin16tospeexwb_new,
 	.framein = lintospeex_framein,
 	.frameout = lintospeex_frameout,
@@ -505,6 +497,19 @@ static int load_module(void)
 	if (parse_config(0))
 		return AST_MODULE_LOAD_DECLINE;
 
+
+	ast_format_set(&speextolin.src_format, AST_FORMAT_SPEEX, 0);
+	ast_format_set(&speextolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&lintospeex.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintospeex.dst_format, AST_FORMAT_SPEEX, 0);
+
+	ast_format_set(&speexwbtolin16.src_format, AST_FORMAT_SPEEX16, 0);
+	ast_format_set(&speexwbtolin16.dst_format, AST_FORMAT_SLINEAR16, 0);
+
+	ast_format_set(&lin16tospeexwb.src_format, AST_FORMAT_SLINEAR16, 0);
+	ast_format_set(&lin16tospeexwb.dst_format, AST_FORMAT_SPEEX16, 0);
+
 	res |= ast_register_translator(&speextolin);
 	res |= ast_register_translator(&lintospeex);
 	res |= ast_register_translator(&speexwbtolin16);
diff --git a/codecs/codec_ulaw.c b/codecs/codec_ulaw.c
index 07f5da39ddf772d3199328d69f271228f1ef80e3..b5211a585aaee453883b7160e9a5f2ce2ece4a3f 100644
--- a/codecs/codec_ulaw.c
+++ b/codecs/codec_ulaw.c
@@ -78,8 +78,6 @@ static int lintoulaw_framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 
 static struct ast_translator ulawtolin = {
 	.name = "ulawtolin",
-	.srcfmt = AST_FORMAT_ULAW,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.framein = ulawtolin_framein,
 	.sample = ulaw_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -88,8 +86,6 @@ static struct ast_translator ulawtolin = {
 
 static struct ast_translator testlawtolin = {
 	.name = "testlawtolin",
-	.srcfmt = AST_FORMAT_TESTLAW,
-	.dstfmt = AST_FORMAT_SLINEAR,
 	.framein = ulawtolin_framein,
 	.sample = ulaw_sample,
 	.buffer_samples = BUFFER_SAMPLES,
@@ -102,8 +98,6 @@ static struct ast_translator testlawtolin = {
 
 static struct ast_translator lintoulaw = {
 	.name = "lintoulaw",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_ULAW,
 	.framein = lintoulaw_framein,
 	.sample = slin8_sample,
 	.buf_size = BUFFER_SAMPLES,
@@ -112,8 +106,6 @@ static struct ast_translator lintoulaw = {
 
 static struct ast_translator lintotestlaw = {
 	.name = "lintotestlaw",
-	.srcfmt = AST_FORMAT_SLINEAR,
-	.dstfmt = AST_FORMAT_TESTLAW,
 	.framein = lintoulaw_framein,
 	.sample = slin8_sample,
 	.buf_size = BUFFER_SAMPLES,
@@ -141,6 +133,18 @@ static int load_module(void)
 {
 	int res;
 
+	ast_format_set(&lintoulaw.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintoulaw.dst_format, AST_FORMAT_ULAW, 0);
+
+	ast_format_set(&lintotestlaw.src_format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&lintotestlaw.dst_format, AST_FORMAT_TESTLAW, 0);
+
+	ast_format_set(&ulawtolin.src_format, AST_FORMAT_ULAW, 0);
+	ast_format_set(&ulawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
+	ast_format_set(&testlawtolin.src_format, AST_FORMAT_TESTLAW, 0);
+	ast_format_set(&testlawtolin.dst_format, AST_FORMAT_SLINEAR, 0);
+
 	res = ast_register_translator(&ulawtolin);
 	if (!res) {
 		res = ast_register_translator(&lintoulaw);
diff --git a/codecs/ex_adpcm.h b/codecs/ex_adpcm.h
index 8a1a5eea9462cbdef78858df041e31855e478e6b..96b7c51f8a7caa804e92e40979c43615a7f62987 100644
--- a/codecs/ex_adpcm.h
+++ b/codecs/ex_adpcm.h
@@ -19,7 +19,6 @@ static struct ast_frame *adpcm_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_ADPCM,
 		.datalen = sizeof(ex_adpcm),
 		.samples = ARRAY_LEN(ex_adpcm) * 2,
 		.mallocd = 0,
@@ -27,6 +26,7 @@ static struct ast_frame *adpcm_sample(void)
 		.src = __PRETTY_FUNCTION__,
 		.data.ptr = ex_adpcm,
 	};
+	ast_format_set(&f.subclass.format, AST_FORMAT_ADPCM, 0);
 
 	return &f;
 }
diff --git a/codecs/ex_alaw.h b/codecs/ex_alaw.h
index 5a03111fa90b90edb77ab65baf9d334f9f319bc3..bbf8ad982e43274fb39b843d26b30bad028214fb 100644
--- a/codecs/ex_alaw.h
+++ b/codecs/ex_alaw.h
@@ -24,7 +24,6 @@ static struct ast_frame *alaw_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_ALAW,
 		.datalen = sizeof(ex_alaw),
 		.samples = ARRAY_LEN(ex_alaw),
 		.mallocd = 0,
@@ -32,6 +31,6 @@ static struct ast_frame *alaw_sample(void)
 		.src = __PRETTY_FUNCTION__,
 		.data.ptr = ex_alaw,
 	};
-
+	ast_format_set(&f.subclass.format, AST_FORMAT_ALAW, 0);
 	return &f;
 }
diff --git a/codecs/ex_g722.h b/codecs/ex_g722.h
index 61146909e5da43d2ecdef45afaa145fa9168c93d..0e9f22686860c72da3d419708c3d3be3c6bf7c77 100644
--- a/codecs/ex_g722.h
+++ b/codecs/ex_g722.h
@@ -34,7 +34,6 @@ static struct ast_frame *g722_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_G722,
 		.datalen = sizeof(ex_g722),
 		.samples = ARRAY_LEN(ex_g722),
 		.mallocd = 0,
@@ -43,5 +42,7 @@ static struct ast_frame *g722_sample(void)
 		.data.ptr = ex_g722,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_G722, 0);
+
 	return &f;
 }
diff --git a/codecs/ex_g726.h b/codecs/ex_g726.h
index 622418a27a05642f0da106f4345be8809d2ef1be..d5438c91a38fca382478a89c9fbdd1b6c2e5765d 100644
--- a/codecs/ex_g726.h
+++ b/codecs/ex_g726.h
@@ -19,7 +19,6 @@ static struct ast_frame *g726_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_G726,
 		.datalen = sizeof(ex_g726),
 		.samples = ARRAY_LEN(ex_g726) * 2, /* 2 samples per byte */
 		.mallocd = 0,
@@ -28,5 +27,7 @@ static struct ast_frame *g726_sample(void)
 		.data.ptr = ex_g726,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_G726, 0);
+
 	return &f;
 }
diff --git a/codecs/ex_gsm.h b/codecs/ex_gsm.h
index 0e4cffab079cfaf122b8391a7dcbfa31294f38e6..8f8b4f9fec4a976425f7f866d7dbe7d73eb007ca 100644
--- a/codecs/ex_gsm.h
+++ b/codecs/ex_gsm.h
@@ -18,7 +18,6 @@ static struct ast_frame *gsm_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_GSM,
 		.datalen = sizeof(ex_gsm),
 		/* All frames are 20 ms long */
 		.samples = GSM_SAMPLES,
@@ -28,5 +27,6 @@ static struct ast_frame *gsm_sample(void)
 		.data.ptr = ex_gsm,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_GSM, 0);
 	return &f;
 }
diff --git a/codecs/ex_lpc10.h b/codecs/ex_lpc10.h
index 9c2ded88bb6a0550aa48e676aa20f043d54dbbce..a36e06addbccfcde24426fb907a522ff0142ab0c 100644
--- a/codecs/ex_lpc10.h
+++ b/codecs/ex_lpc10.h
@@ -15,7 +15,6 @@ static struct ast_frame *lpc10_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_LPC10,
 		.datalen = sizeof(ex_lpc10),
 		/* All frames are 22 ms long (maybe a little more -- why did he choose
 		   LPC10_SAMPLES_PER_FRAME sample frames anyway?? */
@@ -26,5 +25,7 @@ static struct ast_frame *lpc10_sample(void)
 		.data.ptr = ex_lpc10,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_LPC10, 0);
+
 	return &f;
 }
diff --git a/codecs/ex_speex.h b/codecs/ex_speex.h
index 60ccf092e0f51f71228e1b176cca5b8fd31c3147..e9411e5d7b5faf2598c198f7abce41913df24e6f 100644
--- a/codecs/ex_speex.h
+++ b/codecs/ex_speex.h
@@ -18,7 +18,6 @@ static struct ast_frame *speex_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SPEEX,
 		.datalen = sizeof(ex_speex),
 		/* All frames are 20 ms long */
 		.samples = SPEEX_SAMPLES,
@@ -28,6 +27,8 @@ static struct ast_frame *speex_sample(void)
 		.data.ptr = ex_speex,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_SPEEX, 0);
+
 	return &f;
 }
 
@@ -49,7 +50,6 @@ static struct ast_frame *speex16_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SPEEX16,
 		.datalen = sizeof(ex_speex16),
 		/* All frames are 20 ms long */
 		.samples = SPEEX_SAMPLES,
@@ -58,6 +58,7 @@ static struct ast_frame *speex16_sample(void)
 		.src = __PRETTY_FUNCTION__,
 		.data.ptr = ex_speex16,
 	};
+	ast_format_set(&f.subclass.format, AST_FORMAT_SPEEX16, 0);
 
 	return &f;
 }
diff --git a/codecs/ex_ulaw.h b/codecs/ex_ulaw.h
index b3970f5f8142ef477e5ae6d46ecc9155ebdf3cc9..2ab9222fbb19730bbf16466dd6c621f527680741 100644
--- a/codecs/ex_ulaw.h
+++ b/codecs/ex_ulaw.h
@@ -24,7 +24,6 @@ static struct ast_frame *ulaw_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_ULAW,
 		.datalen = sizeof(ex_ulaw),
 		.samples = ARRAY_LEN(ex_ulaw),
 		.mallocd = 0,
@@ -33,5 +32,6 @@ static struct ast_frame *ulaw_sample(void)
 		.data.ptr = ex_ulaw,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_ULAW, 0);
 	return &f;
 }
diff --git a/formats/format_g719.c b/formats/format_g719.c
index c5fc8efaace11cb3bd16d2a6f64a9c5c1c97da7a..b679122f87cf0a0ad1cc4f63f8670d3245eff332 100644
--- a/formats/format_g719.c
+++ b/formats/format_g719.c
@@ -41,7 +41,7 @@ static struct ast_frame *g719read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_G719;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_G719, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -61,8 +61,8 @@ static int g719write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_G719) {
-		ast_log(LOG_WARNING, "Asked to write non-G.719 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_G719) {
+		ast_log(LOG_WARNING, "Asked to write non-G.719 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@@ -110,10 +110,9 @@ static off_t g719tell(struct ast_filestream *fs)
 	return BYTES_TO_SAMPLES(ftello(fs->f));
 }
 
-static const struct ast_format g719_f = {
+static struct ast_format_def g719_f = {
 	.name = "g719",
 	.exts = "g719",
-	.format = AST_FORMAT_G719,
 	.write = g719write,
 	.seek = g719seek,
 	.trunc = g719trunc,
@@ -124,15 +123,15 @@ static const struct ast_format g719_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&g719_f))
+	ast_format_set(&g719_f.format, AST_FORMAT_G719, 0);
+	if (ast_format_def_register(&g719_f))
 		return AST_MODULE_LOAD_DECLINE;
-
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(g719_f.name);
+	return ast_format_def_unregister(g719_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.719",
diff --git a/formats/format_g723.c b/formats/format_g723.c
index 109811609c2409ec3a3d3f4e476a2848165216c1..6dab66a8603f1ac2834c4b38b2069cfe38a51661 100644
--- a/formats/format_g723.c
+++ b/formats/format_g723.c
@@ -61,7 +61,7 @@ static struct ast_frame *g723_read(struct ast_filestream *s, int *whennext)
 	}
 	/* Read the data into the buffer */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_G723_1;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_G723_1, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, size);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != size) {
@@ -82,7 +82,7 @@ static int g723_write(struct ast_filestream *s, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_G723_1) {
+	if (f->subclass.format.id != AST_FORMAT_G723_1) {
 		ast_log(LOG_WARNING, "Asked to write non-g723 frame!\n");
 		return -1;
 	}
@@ -125,10 +125,9 @@ static off_t g723_tell(struct ast_filestream *fs)
 	return -1;
 }
 
-static const struct ast_format g723_1_f = {
+static struct ast_format_def g723_1_f = {
 	.name = "g723sf",
 	.exts = "g723|g723sf",
-	.format = AST_FORMAT_G723_1,
 	.write = g723_write,
 	.seek =	g723_seek,
 	.trunc = g723_trunc,
@@ -139,14 +138,16 @@ static const struct ast_format g723_1_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&g723_1_f))
+	ast_format_set(&g723_1_f.format, AST_FORMAT_G723_1, 0);
+
+	if (ast_format_def_register(&g723_1_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(g723_1_f.name);
+	return ast_format_def_unregister(g723_1_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "G.723.1 Simple Timestamp File Format",
diff --git a/formats/format_g726.c b/formats/format_g726.c
index 3c5697f5d6bb53221afa82cbe9f8ce8f6f303154..73a57c8eef5413b5d027a3d883cc998711b1ad81 100644
--- a/formats/format_g726.c
+++ b/formats/format_g726.c
@@ -119,7 +119,7 @@ static struct ast_frame *g726_read(struct ast_filestream *s, int *whennext)
 
 	/* Send a frame from the file to the appropriate channel */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_G726;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_G726, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, frame_size[fs->rate]);
 	s->fr.samples = 8 * FRAME_TIME;
@@ -141,9 +141,9 @@ static int g726_write(struct ast_filestream *s, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_G726) {
+	if (f->subclass.format.id != AST_FORMAT_G726) {
 		ast_log(LOG_WARNING, "Asked to write non-G726 frame (%s)!\n", 
-						ast_getformatname(f->subclass.codec));
+						ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (f->datalen % frame_size[fs->rate]) {
@@ -174,11 +174,10 @@ static off_t g726_tell(struct ast_filestream *fs)
 	return -1;
 }
 
-static const struct ast_format f[] = {
+static struct ast_format_def f[] = {
 	{
 		.name = "g726-40",
 		.exts = "g726-40",
-		.format = AST_FORMAT_G726,
 		.open = g726_40_open,
 		.rewrite = g726_40_rewrite,
 		.write = g726_write,
@@ -192,7 +191,6 @@ static const struct ast_format f[] = {
 	{
 		.name = "g726-32",
 		.exts = "g726-32",
-		.format = AST_FORMAT_G726,
 		.open = g726_32_open,
 		.rewrite = g726_32_rewrite,
 		.write = g726_write,
@@ -206,7 +204,6 @@ static const struct ast_format f[] = {
 	{
 		.name = "g726-24",
 		.exts = "g726-24",
-		.format = AST_FORMAT_G726,
 		.open = g726_24_open,
 		.rewrite = g726_24_rewrite,
 		.write = g726_write,
@@ -220,7 +217,6 @@ static const struct ast_format f[] = {
 	{
 		.name = "g726-16",
 		.exts = "g726-16",
-		.format = AST_FORMAT_G726,
 		.open = g726_16_open,
 		.rewrite = g726_16_rewrite,
 		.write = g726_write,
@@ -231,15 +227,16 @@ static const struct ast_format f[] = {
 		.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
 		.desc_size = sizeof(struct g726_desc),
 	},
-	{	.format = 0 }	/* terminator */
+	{	.desc_size = 0 }	/* terminator */
 };
 
 static int load_module(void)
 {
 	int i;
 
-	for (i = 0; f[i].format ; i++) {
-		if (ast_format_register(&f[i])) {	/* errors are fatal */
+	for (i = 0; f[i].desc_size ; i++) {
+		ast_format_set(&f[i].format, AST_FORMAT_G726, 0);
+		if (ast_format_def_register(&f[i])) {	/* errors are fatal */
 			ast_log(LOG_WARNING, "Failed to register format %s.\n", f[i].name);
 			return AST_MODULE_LOAD_FAILURE;
 		}
@@ -251,8 +248,8 @@ static int unload_module(void)
 {
 	int i;
 
-	for (i = 0; f[i].format ; i++) {
-		if (ast_format_unregister(f[i].name))
+	for (i = 0; f[i].desc_size ; i++) {
+		if (ast_format_def_unregister(f[i].name))
 			ast_log(LOG_WARNING, "Failed to unregister format %s.\n", f[i].name);
 	}
 	return(0);
diff --git a/formats/format_g729.c b/formats/format_g729.c
index ad7d7fee7db3cea8cfa06a6d5597235ee3b52834..22b3c3282d595a147488b7e2efe58fe19a87b9bf 100644
--- a/formats/format_g729.c
+++ b/formats/format_g729.c
@@ -46,7 +46,7 @@ static struct ast_frame *g729_read(struct ast_filestream *s, int *whennext)
 	int res;
 	/* Send a frame from the file to the appropriate channel */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_G729A;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_G729A, 0);
 	s->fr.mallocd = 0;
 	s->fr.samples = G729A_SAMPLES;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
@@ -66,8 +66,8 @@ static int g729_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_G729A) {
-		ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_G729A) {
+		ast_log(LOG_WARNING, "Asked to write non-G729 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (f->datalen % 10) {
@@ -121,10 +121,9 @@ static off_t g729_tell(struct ast_filestream *fs)
 	return (offset/BUF_SIZE)*G729A_SAMPLES;
 }
 
-static const struct ast_format g729_f = {
+static struct ast_format_def g729_f = {
 	.name = "g729",
 	.exts = "g729",
-	.format = AST_FORMAT_G729A,
 	.write = g729_write,
 	.seek = g729_seek,
 	.trunc = g729_trunc,
@@ -135,14 +134,15 @@ static const struct ast_format g729_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&g729_f))
+	ast_format_set(&g729_f.format, AST_FORMAT_G729A, 0);
+	if (ast_format_def_register(&g729_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(g729_f.name);
+	return ast_format_def_unregister(g729_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw G.729 data",
diff --git a/formats/format_gsm.c b/formats/format_gsm.c
index 2b0b3413e81e6a822c06ae0f66c1bebbd1ed5caa..26257c39fb73bfd3e2d83545df2ec77cc0266010 100644
--- a/formats/format_gsm.c
+++ b/formats/format_gsm.c
@@ -53,7 +53,7 @@ static struct ast_frame *gsm_read(struct ast_filestream *s, int *whennext)
 	int res;
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_GSM;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0);
 	AST_FRAME_SET_BUFFER(&(s->fr), s->buf, AST_FRIENDLY_OFFSET, GSM_FRAME_SIZE)
 	s->fr.mallocd = 0;
 	if ((res = fread(s->fr.data.ptr, 1, GSM_FRAME_SIZE, s->f)) != GSM_FRAME_SIZE) {
@@ -74,8 +74,8 @@ static int gsm_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_GSM) {
-		ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_GSM) {
+		ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (!(f->datalen % 65)) {
@@ -145,10 +145,9 @@ static off_t gsm_tell(struct ast_filestream *fs)
 	return (offset/GSM_FRAME_SIZE)*GSM_SAMPLES;
 }
 
-static const struct ast_format gsm_f = {
+static struct ast_format_def gsm_f = {
 	.name = "gsm",
 	.exts = "gsm",
-	.format = AST_FORMAT_GSM,
 	.write = gsm_write,
 	.seek =	gsm_seek,
 	.trunc = gsm_trunc,
@@ -159,14 +158,15 @@ static const struct ast_format gsm_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&gsm_f))
+	ast_format_set(&gsm_f.format, AST_FORMAT_GSM, 0);
+	if (ast_format_def_register(&gsm_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(gsm_f.name);
+	return ast_format_def_unregister(gsm_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw GSM data",
diff --git a/formats/format_h263.c b/formats/format_h263.c
index 12c9d017075bb78321fff4b220db0d9c076f0a16..76555a67c927fc7f1735dd85f8e48cb97625b1fe 100644
--- a/formats/format_h263.c
+++ b/formats/format_h263.c
@@ -64,7 +64,7 @@ static int h263_open(struct ast_filestream *s)
 static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
 {
 	int res;
-	format_t mark;
+	uint32_t mark;
 	unsigned short len;
 	unsigned int ts;
 	struct h263_desc *fs = (struct h263_desc *)s->_private;
@@ -80,7 +80,7 @@ static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
 		return NULL;
 	}
 	s->fr.frametype = AST_FRAME_VIDEO;
-	s->fr.subclass.codec = AST_FORMAT_H263;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_H263, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -90,7 +90,9 @@ static struct ast_frame *h263_read(struct ast_filestream *s, int *whennext)
 	}
 	s->fr.samples = fs->lastts;	/* XXX what ? */
 	s->fr.datalen = len;
-	s->fr.subclass.codec |= mark;
+	if (mark) {
+		ast_format_set_video_mark(&s->fr.subclass.format);
+	}
 	s->fr.delivery.tv_sec = 0;
 	s->fr.delivery.tv_usec = 0;
 	if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
@@ -106,18 +108,14 @@ static int h263_write(struct ast_filestream *fs, struct ast_frame *f)
 	int res;
 	unsigned int ts;
 	unsigned short len;
-	format_t subclass;
-	format_t mark=0;
+	uint32_t mark = 0;
 	if (f->frametype != AST_FRAME_VIDEO) {
 		ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
 		return -1;
 	}
-	subclass = f->subclass.codec;
-	if (subclass & 0x1)
-		mark=0x8000;
-	subclass &= ~0x1;
-	if (subclass != AST_FORMAT_H263) {
-		ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	mark = ast_format_get_video_mark(&f->subclass.format) ? 0x8000 : 0;
+	if (f->subclass.format.id != AST_FORMAT_H263) {
+		ast_log(LOG_WARNING, "Asked to write non-h263 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	ts = htonl(f->samples);
@@ -157,10 +155,9 @@ static off_t h263_tell(struct ast_filestream *fs)
 	return offset;	/* XXX totally bogus, needs fixing */
 }
 
-static const struct ast_format h263_f = {
+static struct ast_format_def h263_f = {
 	.name = "h263",
 	.exts = "h263",
-	.format = AST_FORMAT_H263,
 	.open = h263_open,
 	.write = h263_write,
 	.seek = h263_seek,
@@ -173,14 +170,15 @@ static const struct ast_format h263_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&h263_f))
+	ast_format_set(&h263_f.format, AST_FORMAT_H263, 0);
+	if (ast_format_def_register(&h263_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(h263_f.name);
+	return ast_format_def_unregister(h263_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.263 data",
diff --git a/formats/format_h264.c b/formats/format_h264.c
index f8fe75c427e1106c06f42de6674ed3e083bab11c..ea82454f3569b2c7e491125ad00b1dde1495584e 100644
--- a/formats/format_h264.c
+++ b/formats/format_h264.c
@@ -56,7 +56,7 @@ static int h264_open(struct ast_filestream *s)
 static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
 {
 	int res;
-	int mark=0;
+	int mark = 0;
 	unsigned short len;
 	unsigned int ts;
 	struct h264_desc *fs = (struct h264_desc *)s->_private;
@@ -72,7 +72,7 @@ static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
 		len = BUF_SIZE;	/* XXX truncate */
 	}
 	s->fr.frametype = AST_FRAME_VIDEO;
-	s->fr.subclass.codec = AST_FORMAT_H264;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_H264, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, len);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -82,7 +82,9 @@ static struct ast_frame *h264_read(struct ast_filestream *s, int *whennext)
 	}
 	s->fr.samples = fs->lastts;
 	s->fr.datalen = len;
-	s->fr.subclass.codec |= mark;
+	if (mark) {
+		ast_format_set_video_mark(&s->fr.subclass.format);
+	}
 	s->fr.delivery.tv_sec = 0;
 	s->fr.delivery.tv_usec = 0;
 	if ((res = fread(&ts, 1, sizeof(ts), s->f)) == sizeof(ts)) {
@@ -104,9 +106,9 @@ static int h264_write(struct ast_filestream *s, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-video frame!\n");
 		return -1;
 	}
-	mark = (f->subclass.codec & 0x1) ? 0x8000 : 0;
-	if ((f->subclass.codec & ~0x1) != AST_FORMAT_H264) {
-		ast_log(LOG_WARNING, "Asked to write non-h264 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	mark = ast_format_get_video_mark(&f->subclass.format) ? 0x8000 : 0;
+	if (f->subclass.format.id != AST_FORMAT_H264) {
+		ast_log(LOG_WARNING, "Asked to write non-h264 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	ts = htonl(f->samples);
@@ -146,10 +148,9 @@ static off_t h264_tell(struct ast_filestream *fs)
 	return offset; /* XXX totally bogus, needs fixing */
 }
 
-static const struct ast_format h264_f = {
+static struct ast_format_def h264_f = {
 	.name = "h264",
 	.exts = "h264",
-	.format = AST_FORMAT_H264,
 	.open = h264_open,
 	.write = h264_write,
 	.seek = h264_seek,
@@ -162,14 +163,15 @@ static const struct ast_format h264_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&h264_f))
+	ast_format_set(&h264_f.format, AST_FORMAT_H264, 0);
+	if (ast_format_def_register(&h264_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(h264_f.name);
+	return ast_format_def_unregister(h264_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw H.264 data",
diff --git a/formats/format_ilbc.c b/formats/format_ilbc.c
index 40bda2639382d24c683ff6ec3637bbb08f38e2a9..a60b585d7186a26a6c3d83c4d2de32c0e4c054e0 100644
--- a/formats/format_ilbc.c
+++ b/formats/format_ilbc.c
@@ -45,7 +45,7 @@ static struct ast_frame *ilbc_read(struct ast_filestream *s, int *whennext)
 	int res;
 	/* Send a frame from the file to the appropriate channel */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_ILBC;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_ILBC, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, ILBC_BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -64,8 +64,8 @@ static int ilbc_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_ILBC) {
-		ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_ILBC) {
+		ast_log(LOG_WARNING, "Asked to write non-iLBC frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (f->datalen % 50) {
@@ -119,10 +119,9 @@ static off_t ilbc_tell(struct ast_filestream *fs)
 	return (offset/ILBC_BUF_SIZE)*ILBC_SAMPLES;
 }
 
-static const struct ast_format ilbc_f = {
+static struct ast_format_def ilbc_f = {
 	.name = "iLBC",
 	.exts = "ilbc",
-	.format = AST_FORMAT_ILBC,
 	.write = ilbc_write,
 	.seek = ilbc_seek,
 	.trunc = ilbc_trunc,
@@ -133,14 +132,15 @@ static const struct ast_format ilbc_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&ilbc_f))
+	ast_format_set(&ilbc_f.format, AST_FORMAT_ILBC, 0);
+	if (ast_format_def_register(&ilbc_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(ilbc_f.name);
+	return ast_format_def_unregister(ilbc_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw iLBC data",
diff --git a/formats/format_jpeg.c b/formats/format_jpeg.c
index 9b1fb99652d96b6d72e0cc918359454467a12216..99de8dac1b4496ad38b8eaace2ee2f09e27f916e 100644
--- a/formats/format_jpeg.c
+++ b/formats/format_jpeg.c
@@ -48,7 +48,7 @@ static struct ast_frame *jpeg_read_image(int fd, int len)
 	}
 	memset(&fr, 0, sizeof(fr));
 	fr.frametype = AST_FRAME_IMAGE;
-	fr.subclass.codec = AST_FORMAT_JPEG;
+	ast_format_set(&fr.subclass.format, AST_FORMAT_JPEG, 0);
 	fr.data.ptr = buf;
 	fr.src = "JPEG Read";
 	fr.datalen = len;
@@ -74,7 +74,7 @@ static int jpeg_write_image(int fd, struct ast_frame *fr)
 		ast_log(LOG_WARNING, "Not an image\n");
 		return -1;
 	}
-	if (fr->subclass.codec != AST_FORMAT_JPEG) {
+	if (fr->subclass.format.id != AST_FORMAT_JPEG) {
 		ast_log(LOG_WARNING, "Not a jpeg image\n");
 		return -1;
 	}
@@ -92,7 +92,6 @@ static struct ast_imager jpeg_format = {
 	.name = "jpg",
 	.desc = "JPEG (Joint Picture Experts Group)",
 	.exts = "jpg|jpeg",
-	.format = AST_FORMAT_JPEG,
 	.read_image = jpeg_read_image,
 	.identify = jpeg_identify,
 	.write_image = jpeg_write_image,
@@ -100,6 +99,7 @@ static struct ast_imager jpeg_format = {
 
 static int load_module(void)
 {
+	ast_format_set(&jpeg_format.format, AST_FORMAT_JPEG, 0);
 	if (ast_image_register(&jpeg_format))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
diff --git a/formats/format_ogg_vorbis.c b/formats/format_ogg_vorbis.c
index d2a08736084bfe4946014988e184fa175b1205c7..949a13f78b3823a91adedf8807ad88634ee56296 100644
--- a/formats/format_ogg_vorbis.c
+++ b/formats/format_ogg_vorbis.c
@@ -291,9 +291,9 @@ static int ogg_vorbis_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_SLINEAR) {
+	if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
 		ast_log(LOG_WARNING, "Asked to write non-SLINEAR frame (%s)!\n",
-			ast_getformatname(f->subclass.codec));
+			ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (!f->datalen)
@@ -438,7 +438,7 @@ static struct ast_frame *ogg_vorbis_read(struct ast_filestream *fs,
 	short *buf;	/* SLIN data buffer */
 
 	fs->fr.frametype = AST_FRAME_VOICE;
-	fs->fr.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&fs->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
 	fs->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&fs->fr, fs->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	buf = (short *)(fs->fr.data.ptr);	/* SLIN data buffer */
@@ -528,10 +528,9 @@ static off_t ogg_vorbis_tell(struct ast_filestream *s)
 	return -1;
 }
 
-static const struct ast_format vorbis_f = {
+static struct ast_format_def vorbis_f = {
 	.name = "ogg_vorbis",
 	.exts = "ogg",
-	.format = AST_FORMAT_SLINEAR,
 	.open = ogg_vorbis_open,
 	.rewrite = ogg_vorbis_rewrite,
 	.write = ogg_vorbis_write,
@@ -546,14 +545,15 @@ static const struct ast_format vorbis_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&vorbis_f))
+	ast_format_set(&vorbis_f.format, AST_FORMAT_SLINEAR, 0);
+	if (ast_format_def_register(&vorbis_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(vorbis_f.name);
+	return ast_format_def_unregister(vorbis_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "OGG/Vorbis audio",
diff --git a/formats/format_pcm.c b/formats/format_pcm.c
index 76eb9c6af19dc6686156411dd4a3ae849196f58c..ec628c5b3043ca0d1d7736c18d7f3195e122bb3d 100644
--- a/formats/format_pcm.c
+++ b/formats/format_pcm.c
@@ -80,7 +80,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = s->fmt->format;
+	ast_format_copy(&s->fr.subclass.format, &s->fmt->format);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@@ -89,7 +89,7 @@ static struct ast_frame *pcm_read(struct ast_filestream *s, int *whennext)
 		return NULL;
 	}
 	s->fr.datalen = res;
-	if (s->fmt->format == AST_FORMAT_G722)
+	if (s->fmt->format.id == AST_FORMAT_G722)
 		*whennext = s->fr.samples = res * 2;
 	else
 		*whennext = s->fr.samples = res;
@@ -126,7 +126,7 @@ static int pcm_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
 	}
 	if (whence == SEEK_FORCECUR && offset > max) { /* extend the file */
 		size_t left = offset - max;
-		const char *src = (fs->fmt->format == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence;
+		const char *src = (fs->fmt->format.id == AST_FORMAT_ALAW) ? alaw_silence : ulaw_silence;
 
 		while (left) {
 			size_t written = fwrite(src, 1, (left > BUF_SIZE) ? BUF_SIZE : left, fs->f);
@@ -163,8 +163,8 @@ static int pcm_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != fs->fmt->format) {
-		ast_log(LOG_WARNING, "Asked to write incompatible format frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) == AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_log(LOG_WARNING, "Asked to write incompatible format frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 
@@ -373,7 +373,7 @@ static int au_seek(struct ast_filestream *fs, off_t sample_offset, int whence)
 	off_t min, max, cur;
 	long offset = 0, bytes;
 
-	if (fs->fmt->format == AST_FORMAT_G722)
+	if (fs->fmt->format.id == AST_FORMAT_G722)
 		bytes = sample_offset / 2;
 	else
 		bytes = sample_offset;
@@ -413,10 +413,9 @@ static off_t au_tell(struct ast_filestream *fs)
 	return offset - AU_HEADER_SIZE;
 }
 
-static const struct ast_format alaw_f = {
+static struct ast_format_def alaw_f = {
 	.name = "alaw",
 	.exts = "alaw|al|alw",
-	.format = AST_FORMAT_ALAW,
 	.write = pcm_write,
 	.seek = pcm_seek,
 	.trunc = pcm_trunc,
@@ -430,10 +429,9 @@ static const struct ast_format alaw_f = {
 #endif
 };
 
-static const struct ast_format pcm_f = {
+static struct ast_format_def pcm_f = {
 	.name = "pcm",
 	.exts = "pcm|ulaw|ul|mu|ulw",
-	.format = AST_FORMAT_ULAW,
 	.write = pcm_write,
 	.seek = pcm_seek,
 	.trunc = pcm_trunc,
@@ -442,10 +440,9 @@ static const struct ast_format pcm_f = {
 	.buf_size = BUF_SIZE + AST_FRIENDLY_OFFSET,
 };
 
-static const struct ast_format g722_f = {
+static struct ast_format_def g722_f = {
 	.name = "g722",
 	.exts = "g722",
-	.format = AST_FORMAT_G722,
 	.write = pcm_write,
 	.seek = pcm_seek,
 	.trunc = pcm_trunc,
@@ -454,10 +451,9 @@ static const struct ast_format g722_f = {
 	.buf_size = (BUF_SIZE * 2) + AST_FRIENDLY_OFFSET,
 };
 
-static const struct ast_format au_f = {
+static struct ast_format_def au_f = {
 	.name = "au",
 	.exts = "au",
-	.format = AST_FORMAT_ULAW,
 	.open = au_open,
 	.rewrite = au_rewrite,
 	.write = pcm_write,
@@ -478,20 +474,24 @@ static int load_module(void)
 	for (i = 0; i < ARRAY_LEN(alaw_silence); i++)
 		alaw_silence[i] = AST_LIN2A(0);
 
-	if ( ast_format_register(&pcm_f)
-		|| ast_format_register(&alaw_f)
-		|| ast_format_register(&au_f)
-		|| ast_format_register(&g722_f) )
+	ast_format_set(&pcm_f.format, AST_FORMAT_ULAW, 0);
+	ast_format_set(&alaw_f.format, AST_FORMAT_ALAW, 0);
+	ast_format_set(&au_f.format, AST_FORMAT_ULAW, 0);
+	ast_format_set(&g722_f.format, AST_FORMAT_G722, 0);
+	if ( ast_format_def_register(&pcm_f)
+		|| ast_format_def_register(&alaw_f)
+		|| ast_format_def_register(&au_f)
+		|| ast_format_def_register(&g722_f) )
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(pcm_f.name)
-		|| ast_format_unregister(alaw_f.name)
-		|| ast_format_unregister(au_f.name)
-		|| ast_format_unregister(g722_f.name);
+	return ast_format_def_unregister(pcm_f.name)
+		|| ast_format_def_unregister(alaw_f.name)
+		|| ast_format_def_unregister(au_f.name)
+		|| ast_format_def_unregister(g722_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw/Sun uLaw/ALaw 8KHz (PCM,PCMA,AU), G.722 16Khz",
diff --git a/formats/format_siren14.c b/formats/format_siren14.c
index 0b8526bde63ff53643b62791c3eb8cfc9dda0b90..53c9ea92211066017f3b450c757ed94b85b67fd8 100644
--- a/formats/format_siren14.c
+++ b/formats/format_siren14.c
@@ -41,7 +41,7 @@ static struct ast_frame *siren14read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_SIREN14;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SIREN14, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -61,8 +61,8 @@ static int siren14write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_SIREN14) {
-		ast_log(LOG_WARNING, "Asked to write non-Siren14 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_SIREN14) {
+		ast_log(LOG_WARNING, "Asked to write non-Siren14 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@@ -110,10 +110,9 @@ static off_t siren14tell(struct ast_filestream *fs)
 	return BYTES_TO_SAMPLES(ftello(fs->f));
 }
 
-static const struct ast_format siren14_f = {
+static struct ast_format_def siren14_f = {
 	.name = "siren14",
 	.exts = "siren14",
-	.format = AST_FORMAT_SIREN14,
 	.write = siren14write,
 	.seek = siren14seek,
 	.trunc = siren14trunc,
@@ -124,7 +123,8 @@ static const struct ast_format siren14_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&siren14_f))
+	ast_format_set(&siren14_f.format, AST_FORMAT_SIREN14, 0);
+	if (ast_format_def_register(&siren14_f))
 		return AST_MODULE_LOAD_DECLINE;
 
 	return AST_MODULE_LOAD_SUCCESS;
@@ -132,7 +132,7 @@ static int load_module(void)
 
 static int unload_module(void)
 {
-	return ast_format_unregister(siren14_f.name);
+	return ast_format_def_unregister(siren14_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.722.1 Annex C (Siren14, licensed from Polycom)",
diff --git a/formats/format_siren7.c b/formats/format_siren7.c
index 5c7919307b4beab24f064832e28fbd8f7b57a6d7..16eca5df59d9235185c8ef8b864ad6d157ac9ad5 100644
--- a/formats/format_siren7.c
+++ b/formats/format_siren7.c
@@ -41,7 +41,7 @@ static struct ast_frame *siren7read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_SIREN7;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SIREN7, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) != s->fr.datalen) {
@@ -61,8 +61,8 @@ static int siren7write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_SIREN7) {
-		ast_log(LOG_WARNING, "Asked to write non-Siren7 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_SIREN7) {
+		ast_log(LOG_WARNING, "Asked to write non-Siren7 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@@ -110,10 +110,9 @@ static off_t siren7tell(struct ast_filestream *fs)
 	return BYTES_TO_SAMPLES(ftello(fs->f));
 }
 
-static const struct ast_format siren7_f = {
+static struct ast_format_def siren7_f = {
 	.name = "siren7",
 	.exts = "siren7",
-	.format = AST_FORMAT_SIREN7,
 	.write = siren7write,
 	.seek = siren7seek,
 	.trunc = siren7trunc,
@@ -124,7 +123,8 @@ static const struct ast_format siren7_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&siren7_f))
+	ast_format_set(&siren7_f.format, AST_FORMAT_SIREN7, 0);
+	if (ast_format_def_register(&siren7_f))
 		return AST_MODULE_LOAD_DECLINE;
 
 	return AST_MODULE_LOAD_SUCCESS;
@@ -132,7 +132,7 @@ static int load_module(void)
 
 static int unload_module(void)
 {
-	return ast_format_unregister(siren7_f.name);
+	return ast_format_def_unregister(siren7_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "ITU G.722.1 (Siren7, licensed from Polycom)",
diff --git a/formats/format_sln.c b/formats/format_sln.c
index 578e64c7baabba9513969e343d62a4d9def0a89b..0cb27949d6883e8de3eaee0317466c56a25fb1a0 100644
--- a/formats/format_sln.c
+++ b/formats/format_sln.c
@@ -39,7 +39,7 @@ static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@@ -59,8 +59,8 @@ static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_SLINEAR) {
-		ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
+		ast_log(LOG_WARNING, "Asked to write non-slinear frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@@ -103,10 +103,9 @@ static off_t slinear_tell(struct ast_filestream *fs)
 	return ftello(fs->f) / 2;
 }
 
-static const struct ast_format slin_f = {
+static struct ast_format_def slin_f = {
 	.name = "sln",
 	.exts = "sln|raw",
-	.format = AST_FORMAT_SLINEAR,
 	.write = slinear_write,
 	.seek = slinear_seek,
 	.trunc = slinear_trunc,
@@ -117,14 +116,15 @@ static const struct ast_format slin_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&slin_f))
+	ast_format_set(&slin_f.format, AST_FORMAT_SLINEAR, 0);
+	if (ast_format_def_register(&slin_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(slin_f.name);
+	return ast_format_def_unregister(slin_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear Audio support (SLN)",
diff --git a/formats/format_sln16.c b/formats/format_sln16.c
index 1e324941204218d01d0f348a029ec5a29a3a1782..cac019615a8f18f1d08fb914812563003da9fb99 100644
--- a/formats/format_sln16.c
+++ b/formats/format_sln16.c
@@ -40,7 +40,7 @@ static struct ast_frame *slinear_read(struct ast_filestream *s, int *whennext)
 	/* Send a frame from the file to the appropriate channel */
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_SLINEAR16;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_SLINEAR16, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@@ -61,8 +61,8 @@ static int slinear_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_SLINEAR16) {
-		ast_log(LOG_WARNING, "Asked to write non-slinear16 frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_SLINEAR16) {
+		ast_log(LOG_WARNING, "Asked to write non-slinear16 frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, fs->f)) != f->datalen) {
@@ -110,10 +110,9 @@ static off_t slinear_tell(struct ast_filestream *fs)
 	return ftello(fs->f) / 2;
 }
 
-static const struct ast_format slin_f = {
+static struct ast_format_def slin_f = {
 	.name = "sln16",
 	.exts = "sln16",
-	.format = AST_FORMAT_SLINEAR16,
 	.write = slinear_write,
 	.seek = slinear_seek,
 	.trunc = slinear_trunc,
@@ -124,7 +123,8 @@ static const struct ast_format slin_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&slin_f))
+	ast_format_set(&slin_f.format, AST_FORMAT_SLINEAR16, 0);
+	if (ast_format_def_register(&slin_f))
 		return AST_MODULE_LOAD_FAILURE;
 
 	return AST_MODULE_LOAD_SUCCESS;
@@ -132,7 +132,7 @@ static int load_module(void)
 
 static int unload_module(void)
 {
-	return ast_format_unregister(slin_f.name);
+	return ast_format_def_unregister(slin_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Raw Signed Linear 16KHz Audio support (SLN16)",
diff --git a/formats/format_vox.c b/formats/format_vox.c
index c13dd7ac5042ec6f16843c34e54557fac98c9e64..05ecdeeaff6343f1a4678aa627595419b9051a80 100644
--- a/formats/format_vox.c
+++ b/formats/format_vox.c
@@ -41,7 +41,7 @@ static struct ast_frame *vox_read(struct ast_filestream *s, int *whennext)
 
 	/* Send a frame from the file to the appropriate channel */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_ADPCM;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_ADPCM, 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, BUF_SIZE);
 	if ((res = fread(s->fr.data.ptr, 1, s->fr.datalen, s->f)) < 1) {
@@ -61,8 +61,8 @@ static int vox_write(struct ast_filestream *s, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_ADPCM) {
-		ast_log(LOG_WARNING, "Asked to write non-ADPCM frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_ADPCM) {
+		ast_log(LOG_WARNING, "Asked to write non-ADPCM frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if ((res = fwrite(f->data.ptr, 1, f->datalen, s->f)) != f->datalen) {
@@ -108,10 +108,9 @@ static off_t vox_tell(struct ast_filestream *fs)
      return offset; 
 }
 
-static const struct ast_format vox_f = {
+static struct ast_format_def vox_f = {
 	.name = "vox",
 	.exts = "vox",
-	.format = AST_FORMAT_ADPCM,
 	.write = vox_write,
 	.seek = vox_seek,
 	.trunc = vox_trunc,
@@ -122,14 +121,15 @@ static const struct ast_format vox_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&vox_f))
+	ast_format_set(&vox_f.format, AST_FORMAT_ADPCM, 0);
+	if (ast_format_def_register(&vox_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(vox_f.name);
+	return ast_format_def_unregister(vox_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Dialogic VOX (ADPCM) File Format",
diff --git a/formats/format_wav.c b/formats/format_wav.c
index 91a309ef4c116bc546f400ca2274891e10ec2ff9..74c14f21c8af8bd32523f8c37d5c23d76cbdd19c 100644
--- a/formats/format_wav.c
+++ b/formats/format_wav.c
@@ -319,7 +319,7 @@ static int wav_open(struct ast_filestream *s)
 	   if we did, it would go here.  We also might want to check
 	   and be sure it's a valid file.  */
 	struct wav_desc *tmp = (struct wav_desc *)s->_private;
-	if ((tmp->maxlen = check_header(s->f, (s->fmt->format == AST_FORMAT_SLINEAR16 ? 16000 : 8000))) < 0)
+	if ((tmp->maxlen = check_header(s->f, (s->fmt->format.id == AST_FORMAT_SLINEAR16 ? 16000 : 8000))) < 0)
 		return -1;
 	return 0;
 }
@@ -331,7 +331,7 @@ static int wav_rewrite(struct ast_filestream *s, const char *comment)
 	   and be sure it's a valid file.  */
 
 	struct wav_desc *tmp = (struct wav_desc *)s->_private;
-	tmp->hz = (s->fmt->format == AST_FORMAT_SLINEAR16 ? 16000 : 8000);
+	tmp->hz = (s->fmt->format.id == AST_FORMAT_SLINEAR16 ? 16000 : 8000);
 	if (write_header(s->f,tmp->hz))
 		return -1;
 	return 0;
@@ -376,7 +376,7 @@ static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
 		bytes = 0;
 /* 	ast_debug(1, "here: %d, maxlen: %d, bytes: %d\n", here, s->maxlen, bytes); */
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = (fs->hz == 16000 ? AST_FORMAT_SLINEAR16 : AST_FORMAT_SLINEAR);
+	ast_format_set(&s->fr.subclass.format, (fs->hz == 16000 ? AST_FORMAT_SLINEAR16 : AST_FORMAT_SLINEAR), 0);
 	s->fr.mallocd = 0;
 	AST_FRAME_SET_BUFFER(&s->fr, s->buf, AST_FRIENDLY_OFFSET, bytes);
 	
@@ -412,11 +412,11 @@ static int wav_write(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if ((f->subclass.codec != AST_FORMAT_SLINEAR) && (f->subclass.codec != AST_FORMAT_SLINEAR16)) {
-		ast_log(LOG_WARNING, "Asked to write non-SLINEAR%s frame (%s)!\n", s->hz == 16000 ? "16" : "", ast_getformatname(f->subclass.codec));
+	if ((f->subclass.format.id != AST_FORMAT_SLINEAR) && (f->subclass.format.id != AST_FORMAT_SLINEAR16)) {
+		ast_log(LOG_WARNING, "Asked to write non-SLINEAR%s frame (%s)!\n", s->hz == 16000 ? "16" : "", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
-	if (f->subclass.codec != fs->fmt->format) {
+	if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) == AST_FORMAT_CMP_NOT_EQUAL) {
 		ast_log(LOG_WARNING, "Can't change SLINEAR frequency during write\n");
 		return -1;
 	}
@@ -486,10 +486,9 @@ static off_t wav_tell(struct ast_filestream *fs)
 	return (offset - 44)/2;
 }
 
-static const struct ast_format wav16_f = {
+static struct ast_format_def wav16_f = {
 	.name = "wav16",
 	.exts = "wav16",
-	.format = AST_FORMAT_SLINEAR16,
 	.open =	wav_open,
 	.rewrite = wav_rewrite,
 	.write = wav_write,
@@ -502,10 +501,9 @@ static const struct ast_format wav16_f = {
 	.desc_size = sizeof(struct wav_desc),
 };
 
-static const struct ast_format wav_f = {
+static struct ast_format_def wav_f = {
 	.name = "wav",
 	.exts = "wav",
-	.format = AST_FORMAT_SLINEAR,
 	.open =	wav_open,
 	.rewrite = wav_rewrite,
 	.write = wav_write,
@@ -520,16 +518,18 @@ static const struct ast_format wav_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&wav_f)
-		|| ast_format_register(&wav16_f))
+	ast_format_set(&wav_f.format, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&wav16_f.format, AST_FORMAT_SLINEAR16, 0);
+	if (ast_format_def_register(&wav_f)
+		|| ast_format_def_register(&wav16_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(wav_f.name)
-		|| ast_format_unregister(wav16_f.name);
+	return ast_format_def_unregister(wav_f.name)
+		|| ast_format_def_unregister(wav16_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV/WAV16 format (8kHz/16kHz Signed Linear)",
diff --git a/formats/format_wav_gsm.c b/formats/format_wav_gsm.c
index f864f281409c9c319c0ac5492c34976b8e7ae422..ae1f11ed8df7a506d5f3d589b4b8dbb4b2cf700b 100644
--- a/formats/format_wav_gsm.c
+++ b/formats/format_wav_gsm.c
@@ -395,7 +395,7 @@ static struct ast_frame *wav_read(struct ast_filestream *s, int *whennext)
 	struct wavg_desc *fs = (struct wavg_desc *)s->_private;
 
 	s->fr.frametype = AST_FRAME_VOICE;
-	s->fr.subclass.codec = AST_FORMAT_GSM;
+	ast_format_set(&s->fr.subclass.format, AST_FORMAT_GSM, 0);
 	s->fr.offset = AST_FRIENDLY_OFFSET;
 	s->fr.samples = GSM_SAMPLES;
 	s->fr.mallocd = 0;
@@ -432,8 +432,8 @@ static int wav_write(struct ast_filestream *s, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Asked to write non-voice frame!\n");
 		return -1;
 	}
-	if (f->subclass.codec != AST_FORMAT_GSM) {
-		ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(f->subclass.codec));
+	if (f->subclass.format.id != AST_FORMAT_GSM) {
+		ast_log(LOG_WARNING, "Asked to write non-GSM frame (%s)!\n", ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	/* XXX this might fail... if the input is a multiple of MSGSM_FRAME_SIZE
@@ -521,10 +521,9 @@ static off_t wav_tell(struct ast_filestream *fs)
 	return (offset - MSGSM_DATA_OFFSET)/MSGSM_FRAME_SIZE*MSGSM_SAMPLES;
 }
 
-static const struct ast_format wav49_f = {
+static struct ast_format_def wav49_f = {
 	.name = "wav49",
 	.exts = "WAV|wav49",
-	.format = AST_FORMAT_GSM,
 	.open =	wav_open,
 	.rewrite = wav_rewrite,
 	.write = wav_write,
@@ -538,14 +537,15 @@ static const struct ast_format wav49_f = {
 
 static int load_module(void)
 {
-	if (ast_format_register(&wav49_f))
+	ast_format_set(&wav49_f.format, AST_FORMAT_GSM, 0);
+	if (ast_format_def_register(&wav49_f))
 		return AST_MODULE_LOAD_FAILURE;
 	return AST_MODULE_LOAD_SUCCESS;
 }
 
 static int unload_module(void)
 {
-	return ast_format_unregister(wav49_f.name);
+	return ast_format_def_unregister(wav49_f.name);
 }
 
 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Microsoft WAV format (Proprietary GSM)",
diff --git a/funcs/func_channel.c b/funcs/func_channel.c
index c0f85d372b79ba2639c7db9cf068a366de5a7707..548d0590f040561c9d0fc976c399ce2763230608 100644
--- a/funcs/func_channel.c
+++ b/funcs/func_channel.c
@@ -265,27 +265,30 @@ static int func_channel_read(struct ast_channel *chan, const char *function,
 			     char *data, char *buf, size_t len)
 {
 	int ret = 0;
+	char tmp[512];
+	struct ast_format_cap *tmpcap;
 
-	if (!strcasecmp(data, "audionativeformat"))
-		/* use the _multiple version when chan->nativeformats holds multiple formats */
-		/* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_AUDIO_MASK); */
-		ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_AUDIO_MASK), len);
-	else if (!strcasecmp(data, "videonativeformat"))
-		/* use the _multiple version when chan->nativeformats holds multiple formats */
-		/* ast_getformatname_multiple(buf, len, chan->nativeformats & AST_FORMAT_VIDEO_MASK); */
-		ast_copy_string(buf, ast_getformatname(chan->nativeformats & AST_FORMAT_VIDEO_MASK), len);
-	else if (!strcasecmp(data, "audioreadformat"))
-		ast_copy_string(buf, ast_getformatname(chan->readformat), len);
-	else if (!strcasecmp(data, "audiowriteformat"))
-		ast_copy_string(buf, ast_getformatname(chan->writeformat), len);
+	if (!strcasecmp(data, "audionativeformat")) {
+		if ((tmpcap = ast_format_cap_get_type(chan->nativeformats, AST_FORMAT_TYPE_AUDIO))) {
+			ast_copy_string(buf, ast_getformatname_multiple(tmp, sizeof(tmp), tmpcap), len);
+			tmpcap = ast_format_cap_destroy(tmpcap);
+		}
+	} else if (!strcasecmp(data, "videonativeformat")) {
+		if ((tmpcap = ast_format_cap_get_type(chan->nativeformats, AST_FORMAT_TYPE_VIDEO))) {
+			ast_copy_string(buf, ast_getformatname_multiple(tmp, sizeof(tmp), tmpcap), len);
+			tmpcap = ast_format_cap_destroy(tmpcap);
+		}
+	} else if (!strcasecmp(data, "audioreadformat")) {
+		ast_copy_string(buf, ast_getformatname(&chan->readformat), len);
+	} else if (!strcasecmp(data, "audiowriteformat")) {
+		ast_copy_string(buf, ast_getformatname(&chan->writeformat), len);
 #ifdef CHANNEL_TRACE
-	else if (!strcasecmp(data, "trace")) {
+	} else if (!strcasecmp(data, "trace")) {
 		ast_channel_lock(chan);
 		ast_copy_string(buf, ast_channel_trace_is_enabled(chan) ? "1" : "0", len);
 		ast_channel_unlock(chan);
-	}
 #endif
-	else if (!strcasecmp(data, "tonezone") && chan->zone)
+	} else if (!strcasecmp(data, "tonezone") && chan->zone)
 		locked_copy_string(chan, buf, chan->zone->country, len);
 	else if (!strcasecmp(data, "language"))
 		locked_copy_string(chan, buf, chan->language, len);
@@ -349,9 +352,9 @@ static int func_channel_read(struct ast_channel *chan, const char *function,
 		ast_channel_unlock(chan);
 	} else if (!strcasecmp(data, "uniqueid")) {
 		locked_copy_string(chan, buf, chan->uniqueid, len);
-	} else if (!strcasecmp(data, "transfercapability"))
+	} else if (!strcasecmp(data, "transfercapability")) {
 		locked_copy_string(chan, buf, transfercapability_table[chan->transfercapability & 0x1f], len);
-	else if (!strcasecmp(data, "callgroup")) {
+	} else if (!strcasecmp(data, "callgroup")) {
 		char groupbuf[256];
 		locked_copy_string(chan, buf,  ast_print_group(groupbuf, sizeof(groupbuf), chan->callgroup), len);
 	} else if (!strcasecmp(data, "amaflags")) {
diff --git a/funcs/func_frame_trace.c b/funcs/func_frame_trace.c
index c4c8d397885e7a0962acfd7856ca692bde1dc5c3..5863b27e8ffc7c5b54f0af92d6dd84ee3ee54454 100644
--- a/funcs/func_frame_trace.c
+++ b/funcs/func_frame_trace.c
@@ -209,14 +209,14 @@ static void print_frame(struct ast_frame *frame)
 		break;
 	case AST_FRAME_VOICE:
 		ast_verbose("FrameType: VOICE\n");
-		ast_verbose("Codec: %s\n", ast_getformatname(frame->subclass.codec));
+		ast_verbose("Codec: %s\n", ast_getformatname(&frame->subclass.format));
 		ast_verbose("MS: %ld\n", frame->len);
 		ast_verbose("Samples: %d\n", frame->samples);
 		ast_verbose("Bytes: %d\n", frame->datalen);
 		break;
 	case AST_FRAME_VIDEO:
 		ast_verbose("FrameType: VIDEO\n");
-		ast_verbose("Codec: %s\n", ast_getformatname(frame->subclass.codec));
+		ast_verbose("Codec: %s\n", ast_getformatname(&frame->subclass.format));
 		ast_verbose("MS: %ld\n", frame->len);
 		ast_verbose("Samples: %d\n", frame->samples);
 		ast_verbose("Bytes: %d\n", frame->datalen);
diff --git a/funcs/func_pitchshift.c b/funcs/func_pitchshift.c
index 7b7c9a2caf45e4f078d87db2c491676049f742a0..36fa2f6c4c674bc04a1b7daf330f254924dae1cc 100644
--- a/funcs/func_pitchshift.c
+++ b/funcs/func_pitchshift.c
@@ -170,8 +170,8 @@ static int pitchshift_cb(struct ast_audiohook *audiohook, struct ast_channel *ch
 	}
 	if ((audiohook->status == AST_AUDIOHOOK_STATUS_DONE) ||
 		(f->frametype != AST_FRAME_VOICE) ||
-		((f->subclass.codec != AST_FORMAT_SLINEAR) &&
-		(f->subclass.codec != AST_FORMAT_SLINEAR16))) {
+		((f->subclass.format.id != AST_FORMAT_SLINEAR) &&
+		(f->subclass.format.id != AST_FORMAT_SLINEAR16))) {
 		return -1;
 	}
 
@@ -481,7 +481,7 @@ static int pitch_shift(struct ast_frame *f, float amount, struct fft_data *fft)
 		return 0;
 	}
 	for (samples = 0; samples < f->samples; samples += 32) {
-		smb_pitch_shift(amount, 32, MAX_FRAME_LENGTH, 32, ast_format_rate(f->subclass.codec), fun+samples, fun+samples, fft);
+		smb_pitch_shift(amount, 32, MAX_FRAME_LENGTH, 32, ast_format_rate(&f->subclass.format), fun+samples, fun+samples, fft);
 	}
 
 	return 0;
diff --git a/include/asterisk/abstract_jb.h b/include/asterisk/abstract_jb.h
index 4efa924b8f70d33444a779813e9df045d1d5cc47..d51554b663f30f8f27f16eb8705c546ada3148f9 100644
--- a/include/asterisk/abstract_jb.h
+++ b/include/asterisk/abstract_jb.h
@@ -32,7 +32,7 @@
 
 #include <sys/time.h>
 
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
@@ -97,7 +97,7 @@ struct ast_jb
 	/*! \brief The time the next frame should be played. */
 	long next;
 	/*! \brief Voice format of the last frame in. */
-	format_t last_format;
+	struct ast_format last_format;
 	/*! \brief File for frame timestamp tracing. */
 	FILE *logfile;
 	/*! \brief Jitterbuffer internal state flags. */
diff --git a/include/asterisk/astobj2.h b/include/asterisk/astobj2.h
index ff35599caec85aa2ae513c6db7b5ae876601b49a..bf8dd42baec9602d58086a613abab4b57a1e07aa 100644
--- a/include/asterisk/astobj2.h
+++ b/include/asterisk/astobj2.h
@@ -771,18 +771,20 @@ int ao2_container_count(struct ao2_container *c);
  */
 #ifdef REF_DEBUG
 
-#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_link(arg1, arg2)         __ao2_link_debug((arg1), (arg2), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_t_link(arg1, arg2, arg3) __ao2_link_debug((arg1), (arg2), 0, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_link(arg1, arg2)         __ao2_link_debug((arg1), (arg2), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_link_nolock(arg1, arg2)  __ao2_link_debug((arg1), (arg2), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 #else
 
-#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2))
-#define ao2_link(arg1, arg2)         __ao2_link((arg1), (arg2))
+#define ao2_t_link(arg1, arg2, arg3) __ao2_link((arg1), (arg2), 0)
+#define ao2_link(arg1, arg2)         __ao2_link((arg1), (arg2), 0)
+#define ao2_link_nolock(arg1, arg2)  __ao2_link((arg1), (arg2), OBJ_NOLOCK)
 
 #endif
 
-void *__ao2_link_debug(struct ao2_container *c, void *new_obj, char *tag, char *file, int line, const char *funcname);
-void *__ao2_link(struct ao2_container *c, void *newobj);
+void *__ao2_link_debug(struct ao2_container *c, void *new_obj, int flags, char *tag, char *file, int line, const char *funcname);
+void *__ao2_link(struct ao2_container *c, void *newobj, int flags);
 
 /*!
  * \brief Remove an object from a container
@@ -803,18 +805,20 @@ void *__ao2_link(struct ao2_container *c, void *newobj);
  */
 #ifdef REF_DEBUG
 
-#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
-#define ao2_unlink(arg1, arg2)         __ao2_unlink_debug((arg1), (arg2), "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink_debug((arg1), (arg2), 0, (arg3),  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_unlink(arg1, arg2)         __ao2_unlink_debug((arg1), (arg2), 0, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
+#define ao2_unlink_nolock(arg1, arg2)  __ao2_unlink_debug((arg1), (arg2), OBJ_NOLOCK, "",  __FILE__, __LINE__, __PRETTY_FUNCTION__)
 
 #else
 
-#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2))
-#define ao2_unlink(arg1, arg2)         __ao2_unlink((arg1), (arg2))
+#define ao2_t_unlink(arg1, arg2, arg3) __ao2_unlink((arg1), (arg2), 0)
+#define ao2_unlink(arg1, arg2)         __ao2_unlink((arg1), (arg2), 0)
+#define ao2_unlink_nolock(arg1, arg2)  __ao2_unlink((arg1), (arg2), OBJ_NOLOCK)
 
 #endif
 
-void *__ao2_unlink_debug(struct ao2_container *c, void *obj, char *tag, char *file, int line, const char *funcname);
-void *__ao2_unlink(struct ao2_container *c, void *obj);
+void *__ao2_unlink_debug(struct ao2_container *c, void *obj, int flags, char *tag, char *file, int line, const char *funcname);
+void *__ao2_unlink(struct ao2_container *c, void *obj, int flags);
 
 
 /*@} */
diff --git a/include/asterisk/audiohook.h b/include/asterisk/audiohook.h
index abf6ca34574dfe7ecd089d2ca5afbeca4fd591b1..75e2c876370c606127a855cf1024e4244e77792a 100644
--- a/include/asterisk/audiohook.h
+++ b/include/asterisk/audiohook.h
@@ -30,7 +30,6 @@ extern "C" {
 /* these two are used in struct ast_audiohook */
 #include "asterisk/lock.h"
 #include "asterisk/linkedlists.h"
-#include "asterisk/frame_defs.h"
 #include "asterisk/slinfactory.h"
 
 enum ast_audiohook_type {
@@ -104,7 +103,7 @@ struct ast_audiohook {
 	struct ast_slinfactory write_factory;                  /*!< Factory where frames written to the channel will go through */
 	struct timeval read_time;                              /*!< Last time read factory was fed */
 	struct timeval write_time;                             /*!< Last time write factory was fed */
-	int format;                                            /*!< Format translation path is setup as */
+	struct ast_format format;                              /*!< Format translation path is setup as */
 	struct ast_trans_pvt *trans_pvt;                       /*!< Translation path for reading frames */
 	ast_audiohook_manipulate_callback manipulate_callback; /*!< Manipulation callback */
 	struct ast_audiohook_options options;                  /*!< Applicable options */
@@ -142,7 +141,7 @@ int ast_audiohook_write_frame(struct ast_audiohook *audiohook, enum ast_audiohoo
  * \param format Format of frame remote side wants back
  * \return Returns frame on success, NULL on failure
  */
-struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format);
+struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format);
 
 /*! \brief Attach audiohook to channel
  * \param chan Channel
diff --git a/include/asterisk/bridging.h b/include/asterisk/bridging.h
index 3e34760022bf853296f8b46e2dbecf3438103e7d..810bc3705d57ded424c9721420b55d557144c32f 100644
--- a/include/asterisk/bridging.h
+++ b/include/asterisk/bridging.h
@@ -193,7 +193,7 @@ struct ast_bridge {
  * This creates a simple two party bridge that will be destroyed once one of
  * the channels hangs up.
  */
-struct ast_bridge *ast_bridge_new(format_t capabilities, int flags);
+struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags);
 
 /*! \brief See if it is possible to create a bridge
  *
@@ -211,7 +211,7 @@ struct ast_bridge *ast_bridge_new(format_t capabilities, int flags);
  * This sees if it is possible to create a bridge capable of bridging two channels
  * together.
  */
-int ast_bridge_check(format_t capabilities);
+int ast_bridge_check(uint32_t capabilities);
 
 /*! \brief Destroy a bridge
  *
diff --git a/include/asterisk/bridging_technology.h b/include/asterisk/bridging_technology.h
index 0659abd779be03f6c6bb6ffddd7e9b9a9c98cdf4..c3e22975c28f07b04bb2e1216fdceb6d68141a71 100644
--- a/include/asterisk/bridging_technology.h
+++ b/include/asterisk/bridging_technology.h
@@ -44,8 +44,9 @@ enum ast_bridge_preference {
 struct ast_bridge_technology {
 	/*! Unique name to this bridge technology */
 	const char *name;
-	/*! The capabilities that this bridge technology is capable of */
-	format_t capabilities;
+	/*! The capabilities that this bridge technology is capable of.  This has nothing to do with
+	 * format capabilities. */
+	uint32_t capabilities;
 	/*! Preference level that should be used when determining whether to use this bridge technology or not */
 	enum ast_bridge_preference preference;
 	/*! Callback for when a bridge is being created */
@@ -71,7 +72,7 @@ struct ast_bridge_technology {
 	/*! Callback for poking a bridge thread */
 	int (*poke)(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel);
 	/*! Formats that the bridge technology supports */
-	format_t formats;
+	struct ast_format_cap *format_capabilities;
 	/*! Bit to indicate whether the bridge technology is currently suspended or not */
 	unsigned int suspended:1;
 	/*! Module this bridge technology belongs to. Is used for reference counting when creating/destroying a bridge. */
diff --git a/include/asterisk/callerid.h b/include/asterisk/callerid.h
index e052f64781625a5a511d43cb06e3088747dedff9..c047632b999ba390f063bc86ad160e79225c3e4a 100644
--- a/include/asterisk/callerid.h
+++ b/include/asterisk/callerid.h
@@ -45,7 +45,7 @@
 #ifndef _ASTERISK_CALLERID_H
 #define _ASTERISK_CALLERID_H
 
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
 
 #define MAX_CALLERID_SIZE 32000
 
@@ -75,8 +75,8 @@
 /*! MWI MDMF format -- generate name, callerid, date and MWI fields */
 #define CID_MWI_TYPE_MDMF_FULL	0x02
 
-#define AST_LIN2X(a) ((codec == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a)))
-#define AST_XLAW(a) ((codec == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a)))
+#define AST_LIN2X(a) ((codec->id == AST_FORMAT_ALAW) ? (AST_LIN2A(a)) : (AST_LIN2MU(a)))
+#define AST_XLAW(a) ((codec->id == AST_FORMAT_ALAW) ? (AST_ALAW(a)) : (AST_MULAW(a)))
 
 
 struct callerid_state;
@@ -101,7 +101,7 @@ void callerid_init(void);
  * \return It returns the size
  * (in bytes) of the data (if it returns a size of 0, there is probably an error)
  */
-int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, format_t codec);
+int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec);
 
 /*! \brief Create a callerID state machine
  * \param cid_signalling Type of signalling in use
@@ -124,7 +124,7 @@ struct callerid_state *callerid_new(int cid_signalling);
  * \retval 0 for "needs more samples"
  * \retval 1 if the CallerID spill reception is complete.
  */
-int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec);
+int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec);
 
 /*! \brief Read samples into the state machine.
  * \param cid Which state machine to act upon
@@ -138,7 +138,7 @@ int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int samples,
  * \retval 0 for "needs more samples"
  * \retval 1 if the CallerID spill reception is complete.
  */
-int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, format_t codec);
+int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int samples, struct ast_format *codec);
 
 /*! \brief Extract info out of callerID state machine.  Flags are listed above
  * \param cid Callerid state machine to act upon
@@ -177,7 +177,7 @@ void callerid_free(struct callerid_state *cid);
  * \details
  * Acts like callerid_generate except uses an asterisk format callerid string.
  */
-int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, format_t codec);
+int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec);
 
 /*!
  * \brief Generate message waiting indicator
@@ -192,13 +192,13 @@ int ast_callerid_generate(unsigned char *buf, const char *name, const char *numb
  * \see callerid_generate() for more info as it uses the same encoding
  * \version 1.6.1 changed mdmf parameter to type, added name, number and flags for caller id message generation
  */
-int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_t codec, const char *name,
+int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec, const char *name,
 	const char *number, int flags);
 
 /*! \brief Generate Caller-ID spill but in a format suitable for Call Waiting(tm)'s Caller*ID(tm)
  * \see ast_callerid_generate() for other details
  */
-int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, format_t codec);
+int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec);
 
 /*! \brief Destructively parse inbuf into name and location (or number)
  * \details
@@ -223,7 +223,7 @@ int ast_callerid_parse(char *instr, char **name, char **location);
  * \param codec Which codec (AST_FORMAT_ALAW or AST_FORMAT_ULAW)
  * \return Returns -1 on error (if len is less than 2400), 0 on success.
  */
-int ast_gen_cas(unsigned char *outbuf, int sas, int len, format_t codec);
+int ast_gen_cas(unsigned char *outbuf, int sas, int len, struct ast_format *codec);
 
 /*!
  * \brief Shrink a phone number in place to just digits (more accurately it just removes ()'s, .'s, and -'s...
diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h
index c9156daf1a92e556b4e11a98d4a336ce882f7237..f58ffc76750127b80ba78d04aeecac774f94475f 100644
--- a/include/asterisk/channel.h
+++ b/include/asterisk/channel.h
@@ -507,12 +507,12 @@ struct ast_channel_tech {
 	const char * const type;
 	const char * const description;
 
-	format_t capabilities;  /*!< Bitmap of formats this channel can handle */
+	struct ast_format_cap *capabilities;  /*!< format capabilities this channel can handle */
 
 	int properties;         /*!< Technology Properties */
 
 	/*! \brief Requester - to set up call data structures (pvt's) */
-	struct ast_channel *(* const requester)(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause);
+	struct ast_channel *(* const requester)(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *cause);
 
 	int (* const devicestate)(void *data);	/*!< Devicestate call back */
 
@@ -824,7 +824,7 @@ struct ast_channel {
 	int fdno;					/*!< Which fd had an event detected on */
 	int streamid;					/*!< For streaming playback, the schedule ID */
 	int vstreamid;					/*!< For streaming video playback, the schedule ID */
-	format_t oldwriteformat;		/*!< Original writer format */
+	struct ast_format oldwriteformat;  /*!< Original writer format */
 	int timingfd;					/*!< Timing fd */
 	enum ast_channel_state _state;			/*!< State of line -- Don't write directly, use ast_setstate() */
 	int rings;					/*!< Number of rings so far */
@@ -839,11 +839,11 @@ struct ast_channel {
 	int hangupcause;				/*!< Why is the channel hanged up. See causes.h */
 	unsigned int flags;				/*!< channel flags of AST_FLAG_ type */
 	int alertpipe[2];
-	format_t nativeformats;         /*!< Kinds of data this channel can natively handle */
-	format_t readformat;            /*!< Requested read format (after translation) */
-	format_t writeformat;           /*!< Requested write format (after translation) */
-	format_t rawreadformat;         /*!< Raw read format (before translation) */
-	format_t rawwriteformat;        /*!< Raw write format (before translation) */
+	struct ast_format_cap *nativeformats;         /*!< Kinds of data this channel can natively handle */
+	struct ast_format readformat;            /*!< Requested read format (after translation) */
+	struct ast_format writeformat;           /*!< Requested write format (after translation) */
+	struct ast_format rawreadformat;         /*!< Raw read format (before translation) */
+	struct ast_format rawwriteformat;        /*!< Raw write format (before translation) */
 	unsigned int emulate_dtmf_duration;		/*!< Number of ms left to emulate DTMF for */
 #ifdef HAVE_EPOLL
 	int epfd;
@@ -1252,7 +1252,7 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
  * \brief Requests a channel
  *
  * \param type type of channel to request
- * \param format requested channel format (codec)
+ * \param format capabilities for requested channel
  * \param requestor channel asking for data
  * \param data data to pass to the channel requester
  * \param status status
@@ -1264,14 +1264,14 @@ struct ast_channel *ast_channel_release(struct ast_channel *chan);
  * \retval NULL failure
  * \retval non-NULL channel on success
  */
-struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *status);
+struct ast_channel *ast_request(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int *status);
 
 /*!
  * \brief Request a channel of a given type, with data as optional information used
  *        by the low level module and attempt to place a call on it
  *
  * \param type type of channel to request
- * \param format requested channel format
+ * \param format capabilities for requested channel
  * \param requestor channel asking for data
  * \param data data to pass to the channel requester
  * \param timeout maximum amount of time to wait for an answer
@@ -1282,14 +1282,14 @@ struct ast_channel *ast_request(const char *type, format_t format, const struct
  * \return Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
  * to know if the call was answered or not.
  */
-struct ast_channel *ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data,
+struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data,
 	int timeout, int *reason, const char *cid_num, const char *cid_name);
 
 /*!
  * \brief Request a channel of a given type, with data as optional information used
  * by the low level module and attempt to place a call on it
  * \param type type of channel to request
- * \param format requested channel format
+ * \param format capabilities for requested channel
  * \param requestor channel requesting data
  * \param data data to pass to the channel requester
  * \param timeout maximum amount of time to wait for an answer
@@ -1300,7 +1300,7 @@ struct ast_channel *ast_request_and_dial(const char *type, format_t format, cons
  * \return Returns an ast_channel on success or no answer, NULL on failure.  Check the value of chan->_state
  * to know if the call was answered or not.
  */
-struct ast_channel *__ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data,
+struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data,
 	int timeout, int *reason, const char *cid_num, const char *cid_name, struct outgoing_helper *oh);
 
 /*!
@@ -1308,12 +1308,12 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co
  * \param caller in channel that requested orig
  * \param orig channel being replaced by the call forward channel
  * \param timeout maximum amount of time to wait for setup of new forward channel
- * \param format requested channel format
+ * \param format capabilities for requested channel
  * \param oh outgoing helper used with original channel
  * \param outstate reason why unsuccessful (if uncuccessful)
  * \return Returns the forwarded call's ast_channel on success or NULL on failure
  */
-struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate);
+struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate);
 
 /*!
  * \brief Register a channel technology (a new channel driver)
@@ -1743,22 +1743,54 @@ int ast_write_text(struct ast_channel *chan, struct ast_frame *frame);
 int ast_prod(struct ast_channel *chan);
 
 /*!
- * \brief Sets read format on channel chan
+ * \brief Sets read format on channel chan from capabilities
  * Set read format for channel to whichever component of "format" is best.
  * \param chan channel to change
- * \param format format to change to
+ * \param formats new formats to pick from for reading
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats);
+
+/*!
+ * \brief Sets read format on channel chan
+ * \param chan channel to change
+ * \param formats, format to set for reading
  * \return Returns 0 on success, -1 on failure
  */
-int ast_set_read_format(struct ast_channel *chan, format_t format);
+int ast_set_read_format(struct ast_channel *chan, struct ast_format *format);
+
+/*!
+ * \brief Sets read format on channel chan by id
+ * \param chan channel to change
+ * \param format id to set for reading, only used for formats without attributes
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_read_format_by_id(struct ast_channel *chan, enum ast_format_id id);
 
 /*!
  * \brief Sets write format on channel chan
  * Set write format for channel to whichever component of "format" is best.
  * \param chan channel to change
- * \param format new format for writing
+ * \param formats new formats to pick from for writing
  * \return Returns 0 on success, -1 on failure
  */
-int ast_set_write_format(struct ast_channel *chan, format_t format);
+int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *formats);
+
+/*!
+ * \brief Sets write format on channel chan
+ * \param chan channel to change
+ * \param formats, format to set for writing
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_write_format(struct ast_channel *chan, struct ast_format *format);
+
+/*!
+ * \brief Sets write format on channel chan
+ * \param chan channel to change
+ * \param format id to set for writing, only used for formats without attributes
+ * \return Returns 0 on success, -1 on failure
+ */
+int ast_set_write_format_by_id(struct ast_channel *chan, enum ast_format_id id);
 
 /*!
  * \brief Sends text to a channel
@@ -2023,9 +2055,15 @@ char *ast_transfercapability2str(int transfercapability) attribute_const;
  */
 int ast_channel_setoption(struct ast_channel *channel, int option, void *data, int datalen, int block);
 
-/*! Pick the best codec
- * Choose the best codec...  Uhhh...   Yah. */
-format_t ast_best_codec(format_t fmts);
+/*!
+ * \brief Pick the best codec
+ *
+ * \param capabilities to pick best codec out of
+ * \param result stucture to store the best codec in.
+ * \retval on success, pointer to result structure 
+ * \retval on failure, NULL
+ */
+struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format *result);
 
 
 /*!
diff --git a/include/asterisk/data.h b/include/asterisk/data.h
index 6851bd511f48a4db5b728fa53e258246d62f94e2..e3253377e798326ce6aba97a95ef390470285f73 100644
--- a/include/asterisk/data.h
+++ b/include/asterisk/data.h
@@ -799,6 +799,16 @@ static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, con
 	return ret.value.AST_DATA_IPADDR;
 }
 
+/*!
+ * \brief Add the codec in the root node based on the format parameter.
+ * \param[in] root The astdata root node where to add the codec node.
+ * \param[in] node_name The name of the node where we are going to add the codec.
+ * \param[in] format The codec allowed.
+ * \return < 0 on error.
+ * \return 0 on success.
+ */
+int ast_data_add_codec(struct ast_data *root, const char *node_name, struct ast_format *format);
+
 /*!
  * \brief Add the list of codecs in the root node based on the capability parameter.
  * \param[in] root The astdata root node where to add the codecs node.
@@ -808,7 +818,7 @@ static inline struct in_addr ast_data_retrieve_ipaddr(struct ast_data *tree, con
  * \return < 0 on error.
  * \return 0 on success.
  */
-int ast_data_add_codecs(struct ast_data *root, const char *node_name, format_t capability);
+int ast_data_add_codecs(struct ast_data *root, const char *node_name, struct ast_format_cap *capability);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }
diff --git a/include/asterisk/file.h b/include/asterisk/file.h
index 69de811652abc41ccc6ace7b44e7fd8ddc916f29..4b032510111629ee8cb92b80da4b322c869b2e61 100644
--- a/include/asterisk/file.h
+++ b/include/asterisk/file.h
@@ -90,7 +90,8 @@ int ast_stopstream(struct ast_channel *c);
  * \param fmt the format you wish to check (the extension)
  * \param preflang (the preferred language you wisht to find the file in)
  * See if a given file exists in a given format.  If fmt is NULL,  any format is accepted.
- * \return 0 if file does not exist, non-zero positive otherwise.
+ * \retval 0, false. The file does not exist
+ * \retval 1, true. The file does exist.
  */
 int ast_fileexists(const char *filename, const char *fmt, const char *preflang);
 
diff --git a/include/asterisk/format.h b/include/asterisk/format.h
new file mode 100644
index 0000000000000000000000000000000000000000..09212abc8167b0e56169397abcee8a9426d4ff67
--- /dev/null
+++ b/include/asterisk/format.h
@@ -0,0 +1,310 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * David Vossel <dvossel@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format API
+ *
+ * \author David Vossel <dvossel@digium.com>
+ */
+
+#ifndef _AST_FORMAT_H_
+#define _AST_FORMAT_H_
+
+#define AST_FORMAT_ATTR_SIZE 128
+
+#define AST_FORMAT_INC 100000
+
+/*! This is the value that ends a var list of format attribute
+ * key value pairs. */
+#define AST_FORMAT_ATTR_END -1
+
+/* \brief Format Categories*/
+enum ast_format_type {
+	AST_FORMAT_TYPE_AUDIO = 1 * AST_FORMAT_INC,
+	AST_FORMAT_TYPE_VIDEO = 2 * AST_FORMAT_INC,
+	AST_FORMAT_TYPE_IMAGE = 3 * AST_FORMAT_INC,
+	AST_FORMAT_TYPE_TEXT  = 4 * AST_FORMAT_INC,
+};
+
+enum ast_format_id {
+	/*! G.723.1 compression */
+	AST_FORMAT_G723_1           = 1 + AST_FORMAT_TYPE_AUDIO,
+	/*! GSM compression */
+	AST_FORMAT_GSM              = 2 + AST_FORMAT_TYPE_AUDIO,
+	/*! Raw mu-law data (G.711) */
+	AST_FORMAT_ULAW             = 3 + AST_FORMAT_TYPE_AUDIO,
+	/*! Raw A-law data (G.711) */
+	AST_FORMAT_ALAW             = 4 + AST_FORMAT_TYPE_AUDIO,
+	/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
+	AST_FORMAT_G726_AAL2        = 5 + AST_FORMAT_TYPE_AUDIO,
+	/*! ADPCM (IMA) */
+	AST_FORMAT_ADPCM            = 6 + AST_FORMAT_TYPE_AUDIO,
+	/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
+	AST_FORMAT_SLINEAR          = 7 + AST_FORMAT_TYPE_AUDIO,
+	/*! LPC10, 180 samples/frame */
+	AST_FORMAT_LPC10            = 8 + AST_FORMAT_TYPE_AUDIO,
+	/*! G.729A audio */
+	AST_FORMAT_G729A            = 9 + AST_FORMAT_TYPE_AUDIO,
+	/*! SpeeX Free Compression */
+	AST_FORMAT_SPEEX            = 10 + AST_FORMAT_TYPE_AUDIO,
+	/*! iLBC Free Compression */
+	AST_FORMAT_ILBC             = 11 + AST_FORMAT_TYPE_AUDIO,
+	/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
+	AST_FORMAT_G726             = 12 + AST_FORMAT_TYPE_AUDIO,
+	/*! G.722 */
+	AST_FORMAT_G722             = 13 + AST_FORMAT_TYPE_AUDIO,
+	/*! G.722.1 (also known as Siren7, 32kbps assumed) */
+	AST_FORMAT_SIREN7           = 14 + AST_FORMAT_TYPE_AUDIO,
+	/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
+	AST_FORMAT_SIREN14          = 15 + AST_FORMAT_TYPE_AUDIO,
+	/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
+	AST_FORMAT_SLINEAR16        = 16 + AST_FORMAT_TYPE_AUDIO,
+	/*! G.719 (64 kbps assumed) */
+	AST_FORMAT_G719             = 17 + AST_FORMAT_TYPE_AUDIO,
+	/*! SpeeX Wideband (16kHz) Free Compression */
+	AST_FORMAT_SPEEX16          = 18 + AST_FORMAT_TYPE_AUDIO,
+	/*! Raw mu-law data (G.711) */
+	AST_FORMAT_TESTLAW          = 19 + AST_FORMAT_TYPE_AUDIO,
+
+	/*! H.261 Video */
+	AST_FORMAT_H261             = 1 + AST_FORMAT_TYPE_VIDEO,
+	/*! H.263 Video */
+	AST_FORMAT_H263             = 2 + AST_FORMAT_TYPE_VIDEO,
+	/*! H.263+ Video */
+	AST_FORMAT_H263_PLUS        = 3 + AST_FORMAT_TYPE_VIDEO,
+	/*! H.264 Video */
+	AST_FORMAT_H264             = 4 + AST_FORMAT_TYPE_VIDEO,
+	/*! MPEG4 Video */
+	AST_FORMAT_MP4_VIDEO        = 5 + AST_FORMAT_TYPE_VIDEO,
+
+	/*! JPEG Images */
+	AST_FORMAT_JPEG             = 1 + AST_FORMAT_TYPE_IMAGE,
+	/*! PNG Images */
+	AST_FORMAT_PNG              = 2 + AST_FORMAT_TYPE_IMAGE,
+
+	/*! T.140 RED Text format RFC 4103 */
+	AST_FORMAT_T140RED          = 1 + AST_FORMAT_TYPE_TEXT,
+	/*! T.140 Text format - ITU T.140, RFC 4103 */
+	AST_FORMAT_T140             = 2 + AST_FORMAT_TYPE_TEXT,
+};
+
+/*! Determine what type of media a ast_format_id is. */
+#define AST_FORMAT_GET_TYPE(id) (((int) (id / AST_FORMAT_INC)) * AST_FORMAT_INC)
+
+/*! \brief This structure contains the buffer used for format attributes */
+struct ast_format_attr {
+	/*! The buffer formats can use to represent attributes */
+	uint8_t format_attr[AST_FORMAT_ATTR_SIZE];
+	/*! If a format's payload needs to pass through that a new marker is required
+	 * for RTP, this variable will be set. */
+	uint8_t rtp_marker_bit;
+};
+
+/*! \brief Represents a media format within Asterisk. */
+struct ast_format {
+	/*! The unique id representing this format from all the other formats. */
+	enum ast_format_id id;
+	/*!  Attribute structure used to associate attributes with a format. */
+	struct ast_format_attr fattr;
+};
+
+enum ast_format_cmp_res {
+	/*! structure 1 is identical to structure 2. */
+	AST_FORMAT_CMP_EQUAL = 0,
+	/*! structure 1 contains elements not in structure 2. */
+	AST_FORMAT_CMP_NOT_EQUAL,
+	/*! structure 1 is a proper subset of the elements in structure 2.*/
+	AST_FORMAT_CMP_SUBSET,
+};
+
+/*! \brief A format must register an attribute interface if it requires the use of the format attributes void pointer */
+struct ast_format_attr_interface {
+	/*! format type */
+	enum ast_format_id id;
+
+	/*! \brief Determine if format_attr 1 is a subset of format_attr 2.
+	 *
+	 * \retval ast_format_cmp_res representing the result of comparing fattr1 and fattr2.
+	 */
+	enum ast_format_cmp_res (* const format_attr_cmp)(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2);
+
+	/*! \brief Get joint attributes of same format type if they exist.
+	 *
+	 * \retval 0 if joint attributes exist
+	 * \retval -1 if no joint attributes are present
+	 */
+	int (* const format_attr_get_joint)(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result);
+
+	/*! \brief Set format capabilities from a list of key value pairs ending with AST_FORMAT_ATTR_END.
+	 * \note This function does not need to call va_end of the va_list. */
+	void (* const format_attr_set)(struct ast_format_attr *format_attr, va_list ap);
+};
+
+/*!
+ * \brief This function is used to set an ast_format object to represent a media format
+ * with optional format attributes represented by format specific key value pairs.
+ *
+ * \param format to set
+ * \param id, format id to set on format
+ * \param set_attributes, are there attributes to set on this format. 0 == false, 1 == True.
+ * \param var list of attribute key value pairs, must end with AST_FORMAT_ATTR_END;
+ *
+ * \details Example usage.
+ * ast_format_set(format, AST_FORMAT_ULAW, 0); // no capability attributes are needed for ULAW
+ *
+ * ast_format_set(format, AST_FORMAT_SILK, 1, // SILK has capability attributes.
+ *	  AST_FORMAT_SILK_ATTR_RATE, 24000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 16000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 12000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 8000,
+ *	  AST_FORMAT_ATTR_END);
+ *
+ * \note This function will initialize the ast_format structure.
+ *
+ * \return Pointer to ast_format object, same pointer that is passed in
+ * by the first argument.
+ */
+struct ast_format *ast_format_set(struct ast_format *format, enum ast_format_id id, int set_attributes, ... );
+
+/*!
+ * \brief After ast_format_set has been used on a function, this function can be used to
+ * set additional format attributes to the structure.
+ *
+ * \param format to set
+ * \param var list of attribute key value pairs, must end with AST_FORMAT_ATTR_END;
+ *
+ * \details Example usage.
+ * ast_format_set(format, AST_FORMAT_SILK, 0);
+ * ast_format_append(format, // SILK has capability attributes.
+ *	  AST_FORMAT_SILK_ATTR_RATE, 24000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 16000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 12000,
+ *	  AST_FORMAT_SILK_ATTR_RATE, 8000,
+ *	  AST_FORMAT_ATTR_END);
+ *
+ * \return Pointer to ast_format object, same pointer that is passed in
+ * by the first argument.
+ */
+struct ast_format *ast_format_append(struct ast_format *format, ... );
+
+/*!
+ * \brief Clears the format stucture.
+ */
+void ast_format_clear(struct ast_format *format);
+
+/*!
+ * \brief This function is used to set an ast_format object to represent a media format
+ * with optional capability attributes represented by format specific key value pairs.
+ *
+ * \details Example usage. Is this SILK format capable of 8khz
+ * is_8khz = ast_format_isset(format, AST_FORMAT_SILK_CAP_RATE, 8000);
+ *
+ * \return 0, The format key value pairs are within the capabilities defined in this structure.
+ * \return -1, The format key value pairs are _NOT_ within the capabilities of this structure.
+ */
+int ast_format_isset(struct ast_format *format, ... );
+
+/*!
+ * \brief Compare ast_formats structures
+ *
+ * \retval ast_format_cmp_res representing the result of comparing format1 and format2.
+ */
+enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2);
+
+/*!
+ * \brief Find joint format attributes of two ast_format
+ * structures containing the same uid and return the intersection in the
+ * result structure.
+ *
+ * retval 0, joint attribute capabilities exist.
+ * retval -1, no joint attribute capabilities exist.
+ */
+int ast_format_joint(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result);
+
+/*!
+ * \brief copy format src into format dst.
+ */
+void ast_format_copy(struct ast_format *dst, const struct ast_format *src);
+
+/*!
+ * \brief Set the rtp mark value on the format to indicate to the interface
+ * writing this format's payload that a new RTP marker is necessary.
+ */
+void ast_format_set_video_mark(struct ast_format *format);
+
+/*!
+ * \brief Determine of the marker bit is set or not on this format.
+ *
+ * \retval 1, true
+ * \retval 0, false
+ */
+int ast_format_get_video_mark(const struct ast_format *format);
+
+/*!
+ * \brief ast_format to old bitfield format represenatation
+ *
+ * \note This is only to be used for IAX2 compatibility 
+ *
+ * \retval iax2 representation of ast_format
+ * \retval 0, if no representation existis for iax2
+ */
+uint64_t ast_format_to_old_bitfield(const struct ast_format *format);
+
+/*!
+ * \brief ast_format_id to old bitfield format represenatation
+ *
+ */
+uint64_t ast_format_id_to_old_bitfield(enum ast_format_id id);
+
+/*!
+ * \brief convert old bitfield format to ast_format represenatation
+ * \note This is only to be used for IAX2 compatibility 
+ *
+ * \retval on success, pointer to the dst format in the input parameters
+ * \retval on failure, NULL
+ */
+struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src);
+
+/*!
+ * \brief convert old bitfield format to ast_format_id value
+ */
+enum ast_format_id ast_format_id_from_old_bitfield(uint64_t src);
+
+/*!
+ * \brief register ast_format_attr_interface with core.
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface);
+
+/*!
+ * \brief unregister format_attr interface with core.
+ *
+ * \retval 0 success
+ * \retval -1 failure
+ */
+int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface);
+
+/*!
+ * \brief Init the ast_format attribute interface register container.
+ */
+int ast_format_attr_init(void);
+
+#endif /* _AST_FORMAT_H */
diff --git a/include/asterisk/format_cap.h b/include/asterisk/format_cap.h
new file mode 100644
index 0000000000000000000000000000000000000000..301ec1471e442368bfe1544ac0a028cb517319b0
--- /dev/null
+++ b/include/asterisk/format_cap.h
@@ -0,0 +1,273 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * David Vossel <dvossel@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format Capability API
+ *
+ * \author David Vossel <dvossel@digium.com>
+ */
+
+#ifndef _AST_FORMATCAP_H_
+#define _AST_FORMATCAP_H_
+
+/*! Capabilities are represented by an opaque structure statically defined in format_capability.c */
+struct ast_format_cap;
+
+/*!
+ * \brief Allocate a new ast_format_cap structure.
+ *
+ * \note Allocation of this object assumes locking
+ * is already occuring and that the point of contention
+ * is above this capabilities structure.  For example,
+ * a tech_pvt object referencing a capabilities structure
+ * can use this function as long as it always holds the
+ * tech_pvt lock while accessing its capabilities.
+ *
+ * \retval ast_format_cap object on success.
+ * \retval NULL on failure.
+ */
+struct ast_format_cap *ast_format_cap_alloc_nolock(void);
+
+/*!
+ * \brief Allocate a new ast_format_cap structure with locking
+ *
+ * \note If no other form of locking is taking place, use this function.
+ * This function makes most sense for globally accessible capabilities structures
+ * that have no other means of locking.
+ *
+ * \retval ast_format_cap object on success.
+ * \retval NULL on failure.
+ */
+struct ast_format_cap *ast_format_cap_alloc(void);
+
+/*!
+ * \brief Destroy an ast_format_cap structure.
+ *
+ * \return NULL
+ */
+void *ast_format_cap_destroy(struct ast_format_cap *cap);
+
+/*!
+ * \brief Add format capability to capabilities structure.
+ *
+ * \note A copy of the input format is made and that copy is
+ * what is placed in the ast_format_cap structure.  The actual
+ * input format ptr is not stored.
+ */
+void ast_format_cap_add(struct ast_format_cap *cap, struct ast_format *format);
+
+/*!
+ * \brief Add all formats Asterisk knows about for a specific type to
+ * the capabilities structure.  Formats with attributes are set, but their
+ * attributes are initilized to 0's.  An attribute structure of 0's should
+ * indicate to the format attribute interface that the format has full
+ * capabilities.
+ *
+ * \note A copy of the input format is made and that copy is
+ * what is placed in the ast_format_cap structure.  The actual
+ * input format ptr is not stored.
+ */
+void ast_format_cap_add_all_by_type(struct ast_format_cap *cap, enum ast_format_type type);
+
+/*!
+ * \brief Add all known formats to the capabilities structure using default format attribute. */
+void ast_format_cap_add_all(struct ast_format_cap *cap);
+
+/*!
+ * \brief Append the formats in src to dst
+ */
+void ast_format_cap_append(struct ast_format_cap *dst, const struct ast_format_cap *src);
+
+/*!
+ * \brief Copy all items in src to dst.
+ * \note any items in dst will be removed before copying
+ */
+void ast_format_cap_copy(struct ast_format_cap *dst, const struct ast_format_cap *src);
+
+/*!
+ * \brief create a deep copy of an ast_format_cap structure
+ *
+ * \retval cap on success
+ * \retval NULL on failure
+ */
+struct ast_format_cap *ast_format_cap_dup(const struct ast_format_cap *src);
+
+/*!
+ * \brief determine if a capabilities structure is empty or not
+ *
+ * \retval 1, true is empty
+ * \retval 0, false, not empty
+ */
+int ast_format_cap_is_empty(const struct ast_format_cap *cap);
+
+/*!
+ * \brief Remove format capability from capability structure.
+ *
+ * \Note format must match Exactly to format in ast_format_cap object in order
+ * to be removed.
+ *
+ * \retval 0, remove was successful
+ * \retval -1, remove failed. Could not find format to remove
+ */
+int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format);
+
+/*!
+ * \brief Remove all format capabilities from capability
+ * structure for a specific format id.
+ *
+ * \Note This will remove _ALL_ formats matching the format id from the
+ * capabilities structure.
+ *
+ * \retval 0, remove was successful
+ * \retval -1, remove failed. Could not find formats to remove
+ */
+int ast_format_cap_remove_byid(struct ast_format_cap *cap, enum ast_format_id id);
+
+/*!
+ * \brief Remove all formats matching a specific format type.
+ */
+void ast_format_cap_remove_bytype(struct ast_format_cap *cap, enum ast_format_type type);
+
+/*!
+ * \brief Remove all format capabilities from capability structure
+ */
+void ast_format_cap_remove_all(struct ast_format_cap *cap);
+
+/*!
+ * \brief Remove all previous formats and set a single new format.
+ */
+void ast_format_cap_set(struct ast_format_cap *cap, struct ast_format *format);
+
+/*!
+ * \brief Find if ast_format is within the capabilities of the ast_format_cap object.
+ *
+ * retval 1 format is compatible with formats held in ast_format_cap object.
+ * retval 0 format is not compatible with any formats in ast_format_cap object.
+ */
+int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format);
+
+/*!
+ * \brief is cap1 identical to cap2
+ *
+ * retval 1 true, identical
+ * retval 0 false, not identical
+ */
+int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2);
+
+/*!
+ * \brief Get joint capability structure.
+ *
+ * \note returns an ast_format_cap object containing the joint capabilities on success.  This new
+ * capabilities structure is allocated with _NO_ locking enabled.  If a joint structure requires
+ * locking, allocate it and use the ast_format_cap_joint_copy function to fill it with the joint
+ * capabilities.
+ *
+ * \retval !NULL success, joint capabilties structure with _NO_ locking enabled.
+ * \retval NULL failure
+ */
+struct ast_format_cap *ast_format_cap_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2);
+
+/*!
+ * \brief Get joint capability structure, copy into result capabilities structure
+ *
+ * \retval 1, joint capabilities exist
+ * \retval 0, joint capabilities do not exist
+ */
+int ast_format_cap_joint_copy(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result);
+
+/*!
+ * \brief Find out if capability structures have any joint capabilities without
+ * returning those capabilities.
+ *
+ * \retval 1 true, has joint capabilities
+ * \retval 0 false, failure
+ */
+int ast_format_cap_has_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2);
+
+/*!
+ * \brief Get all capabilities for a specific media type
+ *
+ * \retval !NULL success, new capabilities structure with _NO_ locking enabled on the new structure.
+ * \retval NULL failure
+ */
+struct ast_format_cap *ast_format_cap_get_type(const struct ast_format_cap *cap, enum ast_format_type ftype);
+
+/*!
+ * \brief Find out if the capabilities structure has any formats
+ * of a specific type.
+ *
+ * \retval 1 true
+ * \retval 0 false, no formats of specific type.
+ */
+int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_format_type type);
+
+/*! \brief Start iterating formats */
+void ast_format_cap_iter_start(struct ast_format_cap *cap);
+
+/*!
+ * \brief Next format in interation
+ *
+ * \details
+ * Here is how to use the ast_format_cap iterator.
+ *
+ * 1. call ast_format_cap_iter_start
+ * 2. call ast_format_cap_iter_next in a loop until it returns -1
+ * 3. call ast_format_cap_iter_end to terminate the iterator.
+ *
+ * example:
+ *
+ * ast_format_cap_iter_start(cap);
+ * while (!ast_format_cap_iter_next(cap, &format)) {
+ *
+ * }
+ * ast_format_cap_iter_end(Cap);
+ *
+ * \Note Unless the container was alloced using no_lock, the container
+ * will be locked during the entire iteration until ast_format_cap_iter_end
+ * is called. XXX Remember this, and do not attempt to lock any containers
+ * within this iteration that will violate locking order.
+ *
+ * \retval 0 on success, new format is copied into input format struct
+ * \retval -1, no more formats are present.
+ */
+int ast_format_cap_iter_next(struct ast_format_cap *cap, struct ast_format *format);
+
+/*!
+ * \brief Ends ast_format_cap iteration.
+ * \note this must be call after every ast_format_cap_iter_start
+ */
+void ast_format_cap_iter_end(struct ast_format_cap *cap);
+
+/*!
+ * \brief ast_format_cap to old bitfield format represenatation
+ *
+ * \note This is only to be used for IAX2 compatibility 
+ *
+ * \retval old bitfield representation of ast_format_cap
+ * \retval 0, if no old bitfield capabilities are present in ast_format_cap
+ */
+uint64_t ast_format_cap_to_old_bitfield(const struct ast_format_cap *cap);
+
+/*!
+ * \brief convert old bitfield format to ast_format_cap represenatation
+ * \note This is only to be used for IAX2 compatibility 
+ */
+void ast_format_cap_from_old_bitfield(struct ast_format_cap *dst, uint64_t src);
+
+#endif /* _AST_FORMATCAP_H */
diff --git a/include/asterisk/format_pref.h b/include/asterisk/format_pref.h
new file mode 100644
index 0000000000000000000000000000000000000000..73a0bdc45231450c4ebffdaf47b21ff48c248a23
--- /dev/null
+++ b/include/asterisk/format_pref.h
@@ -0,0 +1,114 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format Preference API
+ */
+
+#ifndef _AST_FORMATPREF_H_
+#define _AST_FORMATPREF_H_
+
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
+
+#define AST_CODEC_PREF_SIZE 64
+struct ast_codec_pref {
+	/*! This array represents the each format in the pref list */
+	struct ast_format formats[AST_CODEC_PREF_SIZE];
+	/*! This array represents the format id's index in the global format list. */
+	char order[AST_CODEC_PREF_SIZE];
+	/*! This array represents the format's framing size if present. */
+	char framing[AST_CODEC_PREF_SIZE];
+};
+
+/*! \page AudioCodecPref Audio Codec Preferences
+
+	In order to negotiate audio codecs in the order they are configured
+	in \<channel\>.conf for a device, we set up codec preference lists
+	in addition to the codec capabilities setting. The capabilities
+	setting is a bitmask of audio and video codecs with no internal
+	order. This will reflect the offer given to the other side, where
+	the prefered codecs will be added to the top of the list in the
+	order indicated by the "allow" lines in the device configuration.
+
+	Video codecs are not included in the preference lists since they
+	can't be transcoded and we just have to pick whatever is supported
+*/
+
+/*!
+ *\brief Initialize an audio codec preference to "no preference".
+ * \arg \ref AudioCodecPref
+*/
+void ast_codec_pref_init(struct ast_codec_pref *pref);
+
+/*!
+ * \brief Codec located at a particular place in the preference index.
+ * \param preference structure to get the codec out of
+ * \param index to retrieve from
+ * \param retult ast_format structure to store the index value in
+ * \return pointer to input ast_format on success, NULL on failure
+*/
+struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int index, struct ast_format *result);
+
+/*! \brief Remove audio a codec from a preference list */
+void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format);
+
+/*! \brief Append a audio codec to a preference list, removing it first if it was already there
+*/
+int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format);
+
+/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there
+*/
+void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing);
+
+/*! \brief Select the best audio format according to preference list from supplied options.
+ * Best audio format is returned in the result format.
+ *
+ * \note If "find_best" is non-zero then if nothing is found, the "Best" format of
+ * the format list is selected and returned in the result structure, otherwise
+ * NULL is returned
+ *
+ * \retval ptr to result struture.
+ * \retval NULL, best codec was not found
+ */
+struct ast_format *ast_codec_choose(struct ast_codec_pref *pref, struct ast_format_cap *cap, int find_best, struct ast_format *result);
+
+/*! \brief Set packet size for codec
+*/
+int ast_codec_pref_setsize(struct ast_codec_pref *pref, struct ast_format *format, int framems);
+
+/*! \brief Get packet size for codec
+*/
+struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, struct ast_format *format);
+
+/*! \brief Dump audio codec preference list into a string */
+int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
+
+/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string
+ * \note Due to a misunderstanding in how codec preferences are stored, this
+ * list starts at 'B', not 'A'.  For backwards compatibility reasons, this
+ * cannot change.
+ * \param pref A codec preference list structure
+ * \param buf A string denoting codec preference, appropriate for use in line transmission
+ * \param size Size of \a buf
+ * \param right Boolean:  if 0, convert from \a buf to \a pref; if 1, convert from \a pref to \a buf.
+ */
+void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
+
+#endif /* _AST_FORMATPREF_H */
diff --git a/include/asterisk/frame.h b/include/asterisk/frame.h
index 0d8fc0b22ba5aa3bc5921c919c2924588d14a2ed..fc7c1a07b2b2a2d2236f9ccb4dc99852de24f5b7 100644
--- a/include/asterisk/frame.h
+++ b/include/asterisk/frame.h
@@ -31,15 +31,11 @@ extern "C" {
 
 #include <sys/time.h>
 
-#include "asterisk/frame_defs.h"
+#include "asterisk/format_pref.h"
+#include "asterisk/format.h"
 #include "asterisk/endian.h"
 #include "asterisk/linkedlists.h"
 
-struct ast_codec_pref {
-	char order[sizeof(format_t) * 8];
-	char framing[sizeof(format_t) * 8];
-};
-
 /*!
  * \page Def_Frame AST Multimedia and signalling frames
  * \section Def_AstFrame What is an ast_frame ?
@@ -134,7 +130,7 @@ enum {
 
 union ast_frame_subclass {
 	int integer;
-	format_t codec;
+	struct ast_format format;
 };
 
 /*! \brief Data structure associated with a single frame of data
@@ -237,78 +233,6 @@ extern struct ast_frame ast_null_frame;
 /*! Reject link request */
 #define AST_HTML_LINKREJECT	20
 
-/* Data formats for capabilities and frames alike */
-/*! G.723.1 compression */
-#define AST_FORMAT_G723_1     (1ULL << 0)
-/*! GSM compression */
-#define AST_FORMAT_GSM        (1ULL << 1)
-/*! Raw mu-law data (G.711) */
-#define AST_FORMAT_ULAW       (1ULL << 2)
-/*! Raw A-law data (G.711) */
-#define AST_FORMAT_ALAW       (1ULL << 3)
-/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
-#define AST_FORMAT_G726_AAL2  (1ULL << 4)
-/*! ADPCM (IMA) */
-#define AST_FORMAT_ADPCM      (1ULL << 5)
-/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
-#define AST_FORMAT_SLINEAR    (1ULL << 6)
-/*! LPC10, 180 samples/frame */
-#define AST_FORMAT_LPC10      (1ULL << 7)
-/*! G.729A audio */
-#define AST_FORMAT_G729A      (1ULL << 8)
-/*! SpeeX Free Compression */
-#define AST_FORMAT_SPEEX      (1ULL << 9)
-/*! iLBC Free Compression */
-#define AST_FORMAT_ILBC       (1ULL << 10)
-/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
-#define AST_FORMAT_G726       (1ULL << 11)
-/*! G.722 */
-#define AST_FORMAT_G722       (1ULL << 12)
-/*! G.722.1 (also known as Siren7, 32kbps assumed) */
-#define AST_FORMAT_SIREN7     (1ULL << 13)
-/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
-#define AST_FORMAT_SIREN14    (1ULL << 14)
-/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
-#define AST_FORMAT_SLINEAR16  (1ULL << 15)
-/*! Maximum audio mask */
-#define AST_FORMAT_AUDIO_MASK 0xFFFF0000FFFFULL
-/*! JPEG Images */
-#define AST_FORMAT_JPEG       (1ULL << 16)
-/*! PNG Images */
-#define AST_FORMAT_PNG        (1ULL << 17)
-/*! H.261 Video */
-#define AST_FORMAT_H261       (1ULL << 18)
-/*! H.263 Video */
-#define AST_FORMAT_H263       (1ULL << 19)
-/*! H.263+ Video */
-#define AST_FORMAT_H263_PLUS  (1ULL << 20)
-/*! H.264 Video */
-#define AST_FORMAT_H264       (1ULL << 21)
-/*! MPEG4 Video */
-#define AST_FORMAT_MP4_VIDEO  (1ULL << 22)
-#define AST_FORMAT_VIDEO_MASK ((((1ULL << 25)-1) & ~(AST_FORMAT_AUDIO_MASK)) | 0x7FFF000000000000ULL)
-/*! T.140 RED Text format RFC 4103 */
-#define AST_FORMAT_T140RED    (1ULL << 26)
-/*! T.140 Text format - ITU T.140, RFC 4103 */
-#define AST_FORMAT_T140       (1ULL << 27)
-/*! Maximum text mask */
-#define AST_FORMAT_MAX_TEXT   (1ULL << 28)
-#define AST_FORMAT_TEXT_MASK  (((1ULL << 30)-1) & ~(AST_FORMAT_AUDIO_MASK) & ~(AST_FORMAT_VIDEO_MASK))
-/*! G.719 (64 kbps assumed) */
-#define AST_FORMAT_G719	      (1ULL << 32)
-/*! SpeeX Wideband (16kHz) Free Compression */
-#define AST_FORMAT_SPEEX16    (1ULL << 33)
-/*! Raw mu-law data (G.711) */
-#define AST_FORMAT_TESTLAW    (1ULL << 47)
-/*! Reserved bit - do not use
- * \warning We use this bit internally for iteration.  Additionally, using this
- * bit will severely break the implementation of codec prefs within IAX2, as we
- * rely on the equivalence of UTF-8 and ASCII.  The codec represented by this
- * bit should use the first two-byte encoding of UTF-8, which is not presently
- * accounted for.  Hence, we reserve this bit as unused.
- */
-#define AST_FORMAT_RESERVED   (1ULL << 63)
-
 enum ast_control_frame_type {
 	AST_CONTROL_HANGUP = 1,		/*!< Other end has hungup */
 	AST_CONTROL_RING = 2,		/*!< Local ring */
@@ -505,7 +429,7 @@ struct ast_option_header {
 
 /*! \brief Definition of supported media formats (codecs) */
 struct ast_format_list {
-	format_t bits;	/*!< bitmask value */
+	enum ast_format_id id;    /*!< The format unique id */
 	char *name;	/*!< short name */
 	int samplespersecond; /*!< Number of samples per second (8000/16000) */
 	char *desc;	/*!< Description */
@@ -573,12 +497,18 @@ void ast_swapcopy_samples(void *dst, const void *src, int samples);
 #define ast_frame_byteswap_be(fr) do { ; } while(0)
 #endif
 
+/*! \brief Parse an "allow" or "deny" line in a channel or device configuration
+        and update the capabilities and pref if provided.
+	Video codecs are not added to codec preference lists, since we can not transcode
+	\return Returns number of errors encountered during parsing
+ */
+int ast_parse_allow_disallow(struct ast_codec_pref *pref, struct ast_format_cap *cap, const char *list, int allowing);
 
 /*! \brief Get the name of a format
  * \param format id of format
  * \return A static string containing the name of the format or "unknown" if unknown.
  */
-char* ast_getformatname(format_t format);
+char* ast_getformatname(struct ast_format *format);
 
 /*! \brief Get the names of a set of formats
  * \param buf a buffer for the output string
@@ -588,21 +518,22 @@ char* ast_getformatname(format_t format);
  * ex: for format=AST_FORMAT_GSM|AST_FORMAT_SPEEX|AST_FORMAT_ILBC it will return "0x602 (GSM|SPEEX|ILBC)"
  * \return The return value is buf.
  */
-char* ast_getformatname_multiple(char *buf, size_t size, format_t format);
+char* ast_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *cap);
 
 /*!
  * \brief Gets a format from a name.
  * \param name string of format
- * \return This returns the form of the format in binary on success, 0 on error.
+ * \param format structure to return the format in.
+ * \return This returns the format pointer given to it on success and NULL on failure
  */
-format_t ast_getformatbyname(const char *name);
+struct ast_format *ast_getformatbyname(const char *name, struct ast_format *format);
 
 /*! \brief Get a name from a format 
  * Gets a name from a format
- * \param codec codec number (1,2,4,8,16,etc.)
+ * \param format to get name of
  * \return This returns a static string identifying the format on success, 0 on error.
  */
-char *ast_codec2str(format_t codec);
+char *ast_codec2str(struct ast_format *format);
 
 /*! \name AST_Smoother 
 */
@@ -654,91 +585,20 @@ const struct ast_format_list *ast_get_format_list_index(int index);
 const struct ast_format_list *ast_get_format_list(size_t *size);
 void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix);
 
-/*! \page AudioCodecPref Audio Codec Preferences
-
-	In order to negotiate audio codecs in the order they are configured
-	in \<channel\>.conf for a device, we set up codec preference lists
-	in addition to the codec capabilities setting. The capabilities
-	setting is a bitmask of audio and video codecs with no internal
-	order. This will reflect the offer given to the other side, where
-	the prefered codecs will be added to the top of the list in the
-	order indicated by the "allow" lines in the device configuration.
-	
-	Video codecs are not included in the preference lists since they
-	can't be transcoded and we just have to pick whatever is supported
-*/
-
-/*! 
- *\brief Initialize an audio codec preference to "no preference".
- * \arg \ref AudioCodecPref 
-*/
-void ast_codec_pref_init(struct ast_codec_pref *pref);
-
-/*! 
- * \brief Codec located at a particular place in the preference index.
- * \arg \ref AudioCodecPref 
-*/
-format_t ast_codec_pref_index(struct ast_codec_pref *pref, int index);
-
-/*! \brief Remove audio a codec from a preference list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, format_t format);
-
-/*! \brief Append a audio codec to a preference list, removing it first if it was already there 
-*/
-int ast_codec_pref_append(struct ast_codec_pref *pref, format_t format);
-
-/*! \brief Prepend an audio codec to a preference list, removing it first if it was already there 
-*/
-void ast_codec_pref_prepend(struct ast_codec_pref *pref, format_t format, int only_if_existing);
-
-/*! \brief Select the best audio format according to preference list from supplied options. 
-   If "find_best" is non-zero then if nothing is found, the "Best" format of 
-   the format list is selected, otherwise 0 is returned. */
-format_t ast_codec_choose(struct ast_codec_pref *pref, format_t formats, int find_best);
-
-/*! \brief Set packet size for codec
-*/
-int ast_codec_pref_setsize(struct ast_codec_pref *pref, format_t format, int framems);
-
-/*! \brief Get packet size for codec
-*/
-struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, format_t format);
-
-/*! \brief Parse an "allow" or "deny" line in a channel or device configuration 
-        and update the capabilities mask and pref if provided.
-	Video codecs are not added to codec preference lists, since we can not transcode
-	\return Returns number of errors encountered during parsing
- */
-int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing);
-
-/*! \brief Dump audio codec preference list into a string */
-int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size);
-
-/*! \brief Shift an audio codec preference list up or down 65 bytes so that it becomes an ASCII string
- * \note Due to a misunderstanding in how codec preferences are stored, this
- * list starts at 'B', not 'A'.  For backwards compatibility reasons, this
- * cannot change.
- * \param pref A codec preference list structure
- * \param buf A string denoting codec preference, appropriate for use in line transmission
- * \param size Size of \a buf
- * \param right Boolean:  if 0, convert from \a buf to \a pref; if 1, convert from \a pref to \a buf.
- */
-void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right);
-
 /*! \brief Returns the number of samples contained in the frame */
 int ast_codec_get_samples(struct ast_frame *f);
 
 /*! \brief Returns the number of bytes for the number of samples of the given format */
-int ast_codec_get_len(format_t format, int samples);
+int ast_codec_get_len(struct ast_format *format, int samples);
 
 /*! \brief Appends a frame to the end of a list of frames, truncating the maximum length of the list */
 struct ast_frame *ast_frame_enqueue(struct ast_frame *head, struct ast_frame *f, int maxlen, int dupe);
 
 
 /*! \brief Gets duration in ms of interpolation frame for a format */
-static inline int ast_codec_interp_len(format_t format) 
+static inline int ast_codec_interp_len(struct ast_format *format)
 { 
-	return (format == AST_FORMAT_ILBC) ? 30 : 20;
+	return (format->id == AST_FORMAT_ILBC) ? 30 : 20;
 }
 
 /*!
@@ -763,9 +623,9 @@ int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2);
 /*!
  * \brief Get the sample rate for a given format.
  */
-static force_inline int ast_format_rate(format_t format)
+static force_inline int ast_format_rate(struct ast_format *format)
 {
-	switch (format) {
+	switch (format->id) {
 	case AST_FORMAT_G722:
 	case AST_FORMAT_SLINEAR16:
 	case AST_FORMAT_SIREN7:
diff --git a/include/asterisk/frame_defs.h b/include/asterisk/frame_defs.h
index 829572d197f0401fa2a7e6e05dfee549b48d3f1b..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 100644
--- a/include/asterisk/frame_defs.h
+++ b/include/asterisk/frame_defs.h
@@ -1,38 +0,0 @@
-/*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 1999 - 2009, Digium, Inc.
- *
- * Mark Spencer <markster@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
-
-/*! \file
- * \brief Asterisk internal frame definitions.
- * \arg For an explanation of frames, see \ref Def_Frame
- * \arg Frames are send of Asterisk channels, see \ref Def_Channel
- */
-
-#ifndef _ASTERISK_FRAME_DEFS_H
-#define _ASTERISK_FRAME_DEFS_H
-
-#if defined(__cplusplus) || defined(c_plusplus)
-extern "C" {
-#endif
-
-typedef int64_t format_t;
-
-#if defined(__cplusplus) || defined(c_plusplus)
-}
-#endif
-
-#endif /* _ASTERISK_FRAME_DEFS_H */
diff --git a/include/asterisk/image.h b/include/asterisk/image.h
index a3e2e015e0eae0d883beb55c7b24af0c97cf246c..302f09e852ddec4b123ebb87dc74188ee0ba536e 100644
--- a/include/asterisk/image.h
+++ b/include/asterisk/image.h
@@ -28,7 +28,7 @@ struct ast_imager {
 	char *name;			/*!< Name */
 	char *desc;			/*!< Description */
 	char *exts;			/*!< Extension(s) (separated by '|' ) */
-	int format;			/*!< Image format */
+	struct ast_format format; /*!< Image format */
 	struct ast_frame *(*read_image)(int fd, int len);	/*!< Read an image from a file descriptor */
 	int (*identify)(int fd);				/*!< Identify if this is that type of file */
 	int (*write_image)(int fd, struct ast_frame *frame);	/*!< Returns length written */
@@ -57,12 +57,12 @@ int ast_send_image(struct ast_channel *chan, const char *filename);
  * \brief Make an image 
  * \param filename filename of image to prepare
  * \param preflang preferred language to get the image...?
- * \param format the format of the file
+ * \param format the format of the file, NULL for any image format
  * Make an image from a filename ??? No estoy positivo
  * \retval an ast_frame on success
  * \retval NULL on failure
  */
-struct ast_frame *ast_read_image(const char *filename, const char *preflang, int format);
+struct ast_frame *ast_read_image(const char *filename, const char *preflang, struct ast_format *format);
 
 /*! 
  * \brief Register image format
diff --git a/include/asterisk/mod_format.h b/include/asterisk/mod_format.h
index 08ee4cc42db44b0edae33ca52c3e9383bcbdd1f4..ff3ab7bbf587d1f6e19f393c5ec8d23ff3cacbe5 100644
--- a/include/asterisk/mod_format.h
+++ b/include/asterisk/mod_format.h
@@ -37,14 +37,14 @@ extern "C" {
  * Not all are necessary, the support routine implement default
  * values for some of them.
  * A handler typically fills a structure initializing the desired
- * fields, and then calls ast_format_register() with the (readonly)
+ * fields, and then calls ast_format_def_register() with the (readonly)
  * structure as an argument.
  */
-struct ast_format {
+struct ast_format_def {
 	char name[80];		/*!< Name of format */
 	char exts[80];		/*!< Extensions (separated by | if more than one) 
 	    			this format can read.  First is assumed for writing (e.g. .mp3) */
-	format_t format;		/*!< Format of frames it uses/provides (one only) */
+	struct ast_format format;	/*!< Format of frames it uses/provides (one only) */
 	/*! 
 	 * \brief Prepare an input stream for playback. 
 	 * \return 0 on success, -1 on error.
@@ -76,7 +76,7 @@ struct ast_format {
 	void (*close)(struct ast_filestream *);
 	char * (*getcomment)(struct ast_filestream *);		/*!< Retrieve file comment */
 
-	AST_LIST_ENTRY(ast_format) list;			/*!< Link */
+	AST_LIST_ENTRY(ast_format_def) list;                /*!< Link */
 
 	/*!
 	 * If the handler needs a buffer (for read, typically)
@@ -99,7 +99,7 @@ struct ast_format {
  */
 struct ast_filestream {
 	/*! Everybody reserves a block of AST_RESERVED_POINTERS pointers for us */
-	struct ast_format *fmt;	/* need to write to the lock and usecnt */
+	struct ast_format_def *fmt;	/* need to write to the lock and usecnt */
 	int flags;
 	mode_t mode;
 	char *open_filename;
@@ -110,7 +110,7 @@ struct ast_filestream {
 	/*! Transparently translate from another format -- just once */
 	struct ast_trans_pvt *trans;
 	struct ast_tranlator_pvt *tr;
-	int lastwriteformat;
+	struct ast_format lastwriteformat;
 	int lasttimeout;
 	struct ast_channel *owner;
 	FILE *f;
@@ -127,8 +127,8 @@ struct ast_filestream {
  * \retval 0 on success
  * \retval -1 on failure
  */
-int __ast_format_register(const struct ast_format *f, struct ast_module *mod);
-#define ast_format_register(f) __ast_format_register(f, ast_module_info->self)
+int __ast_format_def_register(const struct ast_format_def *f, struct ast_module *mod);
+#define ast_format_def_register(f) __ast_format_def_register(f, ast_module_info->self)
 
 /*! 
  * \brief Unregisters a file format 
@@ -137,7 +137,7 @@ int __ast_format_register(const struct ast_format *f, struct ast_module *mod);
  * \retval 0 on success
  * \retval -1 on failure to unregister
  */
-int ast_format_unregister(const char *name);
+int ast_format_def_unregister(const char *name);
 
 #if defined(__cplusplus) || defined(c_plusplus)
 }
diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h
index e80a303f605474a7095b071bc45332654a67129a..429e6053722ce333c466d1345d151cdc1a30c3be 100644
--- a/include/asterisk/pbx.h
+++ b/include/asterisk/pbx.h
@@ -30,7 +30,7 @@
 #include "asterisk/hashtab.h"
 #include "asterisk/stringfields.h"
 #include "asterisk/xmldoc.h"
-#include "asterisk/frame_defs.h"
+#include "asterisk/format.h"
 
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
@@ -887,11 +887,11 @@ int ast_async_goto_by_name(const char *chan, const char *context, const char *ex
 
 /*! Synchronously or asynchronously make an outbound call and send it to a
    particular extension */
-int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
+int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
 
 /*! Synchronously or asynchronously make an outbound call and send it to a
    particular application with given extension */
-int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
+int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *app, const char *appdata, int *reason, int sync, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel);
 
 /*!
  * \brief Evaluate a condition
diff --git a/include/asterisk/rtp_engine.h b/include/asterisk/rtp_engine.h
index cd9179be123b91f7ad91e34a8e59a6b29e2aaf28..f13538321de5a1c4f67a43cc92bc51fb09a85d53 100644
--- a/include/asterisk/rtp_engine.h
+++ b/include/asterisk/rtp_engine.h
@@ -227,8 +227,12 @@ enum ast_rtp_instance_stat {
 struct ast_rtp_payload_type {
 	/*! Is this an Asterisk value */
 	int asterisk_format;
-	/*! Actual internal value of the payload */
-	format_t code;
+	/*! If asterisk_format is set, this is the internal
+	 * asterisk format represented by the payload */
+	struct ast_format format;
+	/*! Actual internal RTP specific value of the payload */
+	int rtp_code;
+
 };
 
 /*! Structure that represents statistics from an RTP instance */
@@ -335,8 +339,8 @@ struct ast_rtp_engine {
 	void *(*extended_prop_get)(struct ast_rtp_instance *instance, int property);
 	/*! Callback for setting an RTP property */
 	void (*prop_set)(struct ast_rtp_instance *instance, enum ast_rtp_property property, int value);
-	/*! Callback for setting a payload */
-	void (*payload_set)(struct ast_rtp_instance *instance, int payload, int astformat, format_t format);
+	/*! Callback for setting a payload.  If asterisk  is to be used, asterisk_format will be set, otherwise value in code is used. */
+	void (*payload_set)(struct ast_rtp_instance *instance, int payload, int asterisk_format, struct ast_format *format, int code);
 	/*! Callback for setting packetization preferences */
 	void (*packetization_set)(struct ast_rtp_instance *instance, struct ast_codec_pref *pref);
 	/*! Callback for setting the remote address that RTP is to be sent to */
@@ -360,9 +364,9 @@ struct ast_rtp_engine {
 	/*! Callback to locally bridge two RTP instances */
 	int (*local_bridge)(struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1);
 	/*! Callback to set the read format */
-	int (*set_read_format)(struct ast_rtp_instance *instance, format_t format);
+	int (*set_read_format)(struct ast_rtp_instance *instance, struct ast_format *format);
 	/*! Callback to set the write format */
-	int (*set_write_format)(struct ast_rtp_instance *instance, format_t format);
+	int (*set_write_format)(struct ast_rtp_instance *instance, struct ast_format *format);
 	/*! Callback to make two instances compatible */
 	int (*make_compatible)(struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1);
 	/*! Callback to see if two instances are compatible with DTMF */
@@ -371,8 +375,8 @@ struct ast_rtp_engine {
 	int (*activate)(struct ast_rtp_instance *instance);
 	/*! Callback to request that the RTP engine send a STUN BIND request */
 	void (*stun_request)(struct ast_rtp_instance *instance, struct ast_sockaddr *suggestion, const char *username);
-	/*! Callback to get the transcodeable formats supported */
-	int (*available_formats)(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk);
+	/*! Callback to get the transcodeable formats supported. result returned in ast_format_cap *result */
+	void (*available_formats)(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result);
 	/*! Linked list information */
 	AST_RWLIST_ENTRY(ast_rtp_engine) entry;
 };
@@ -407,9 +411,9 @@ struct ast_rtp_glue {
 	 */
 	enum ast_rtp_glue_result (*get_trtp_info)(struct ast_channel *chan, struct ast_rtp_instance **instance);
 	/*! Callback for updating the destination that the remote side should send RTP to */
-	int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, format_t codecs, int nat_active);
-	/*! Callback for retrieving codecs that the channel can do */
-	format_t (*get_codec)(struct ast_channel *chan);
+	int (*update_peer)(struct ast_channel *chan, struct ast_rtp_instance *instance, struct ast_rtp_instance *vinstance, struct ast_rtp_instance *tinstance, const struct ast_format_cap *cap, int nat_active);
+	/*! Callback for retrieving codecs that the channel can do.  Result returned in result_cap*/
+	void (*get_codec)(struct ast_channel *chan, struct ast_format_cap *result_cap);
 	/*! Linked list information */
 	AST_RWLIST_ENTRY(ast_rtp_glue) entry;
 };
@@ -1046,27 +1050,29 @@ struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs
 /*!
  * \brief Get the sample rate associated with known RTP payload types
  *
- * \param asterisk_format True if the value in the 'code' parameter is an AST_FORMAT value
- * \param code Format code, either from AST_FORMAT list or from AST_RTP list
+ * \param asterisk_format True if the value in format is to be used.
+ * \param An asterisk format
+ * \param code from AST_RTP list
  *
  * \return the sample rate if the format was found, zero if it was not found
  *
  * \since 1.8
  */
-unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code);
+unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, struct ast_format *format, int code);
 
 /*!
  * \brief Retrieve all formats that were found
  *
  * \param codecs Codecs structure to look in
- * \param astformats An integer to put the Asterisk formats in
+ * \param astformats A capabilities structure to put the Asterisk formats in.
  * \param nonastformats An integer to put the non-Asterisk formats in
  *
  * Example usage:
  *
  * \code
- * int astformats, nonastformats;
- * ast_rtp_codecs_payload_Formats(&codecs, &astformats, &nonastformats);
+ * struct ast_format_cap *astformats = ast_format_cap_alloc_nolock()
+ * int nonastformats;
+ * ast_rtp_codecs_payload_formats(&codecs, &astformats, &nonastformats);
  * \endcode
  *
  * This retrieves all the formats known about in the codecs structure and puts the Asterisk ones in the integer
@@ -1074,13 +1080,14 @@ unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code);
  *
  * \since 1.8
  */
-void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *astformats, int *nonastformats);
+void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats);
 
 /*!
  * \brief Retrieve a payload based on whether it is an Asterisk format and the code
  *
  * \param codecs Codecs structure to look in
- * \param asterisk_format Non-zero if the given code is an Asterisk format value
+ * \param asterisk_format Non-zero if the given Asterisk format is present
+ * \param format Asterisk format to look for
  * \param code The format to look for
  *
  * \retval Numerical payload
@@ -1088,20 +1095,21 @@ void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *ast
  * Example usage:
  *
  * \code
- * int payload = ast_rtp_codecs_payload_code(&codecs, 1, AST_FORMAT_ULAW);
+ * int payload = ast_rtp_codecs_payload_code(&codecs, 1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0);
  * \endcode
  *
  * This looks for the numerical payload for ULAW in the codecs structure.
  *
  * \since 1.8
  */
-int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code);
+int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code);
 
 /*!
  * \brief Retrieve mime subtype information on a payload
  *
- * \param asterisk_format Non-zero if the given code is an Asterisk format value
- * \param code Format to look up
+ * \param asterisk_format Non-zero to look up using Asterisk format
+ * \param format Asterisk format to look up
+ * \param code RTP code to look up
  * \param options Additional options that may change the result
  *
  * \retval Mime subtype success
@@ -1110,21 +1118,22 @@ int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asteris
  * Example usage:
  *
  * \code
- * const char *subtype = ast_rtp_lookup_mime_subtype2(1, AST_FORMAT_ULAW, 0);
+ * const char *subtype = ast_rtp_lookup_mime_subtype2(1, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0), 0, 0);
  * \endcode
  *
  * This looks up the mime subtype for the ULAW format.
  *
  * \since 1.8
  */
-const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options);
+const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_format *format, int code, enum ast_rtp_options options);
 
 /*!
  * \brief Convert formats into a string and put them into a buffer
  *
  * \param buf Buffer to put the mime output into
- * \param capability Formats that we are looking up
- * \param asterisk_format Non-zero if the given capability are Asterisk format capabilities
+ * \param ast_format_capability Asterisk Formats we are looking up.
+ * \param rtp_capability RTP codes that we are looking up
+ * \param asterisk_format Non-zero if the ast_format_capability structure is to be used, 0 if rtp_capability is to be used
  * \param options Additional options that may change the result
  *
  * \retval non-NULL success
@@ -1134,14 +1143,19 @@ const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format
  *
  * \code
  * char buf[256] = "";
- * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), AST_FORMAT_ULAW | AST_FORMAT_ALAW, 1, 0);
+ * struct ast_format tmp_fmt;
+ * struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+ * ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
+ * ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0));
+ * char *mime = ast_rtp_lookup_mime_multiple2(&buf, sizeof(buf), cap, 0, 1, 0);
+ * ast_format_cap_destroy(cap);
  * \endcode
  *
  * This returns the mime values for ULAW and ALAW in the buffer pointed to by buf.
  *
  * \since 1.8
  */
-char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, const format_t capability, const int asterisk_format, enum ast_rtp_options options);
+char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options);
 
 /*!
  * \brief Set codec packetization preferences
@@ -1535,14 +1549,15 @@ char *ast_rtp_instance_get_quality(struct ast_rtp_instance *instance, enum ast_r
  * Example usage:
  *
  * \code
- * ast_rtp_instance_set_read_format(instance, AST_FORMAT_ULAW);
+ * struct ast_format tmp_fmt;
+ * ast_rtp_instance_set_read_format(instance, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
  * \endcode
  *
  * This requests that the RTP engine provide audio frames in the ULAW format.
  *
  * \since 1.8
  */
-int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, format_t format);
+int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format);
 
 /*!
  * \brief Tell underlying RTP engine that audio frames will be provided in a specific format
@@ -1556,14 +1571,15 @@ int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, format_t
  * Example usage:
  *
  * \code
- * ast_rtp_instance_set_write_format(instance, AST_FORMAT_ULAW);
+ * struct ast_format tmp_fmt;
+ * ast_rtp_instance_set_write_format(instance, ast_format_set(&tmp_fmt, AST_FORMAT_ULAW, 0));
  * \endcode
  *
  * This tells the underlying RTP engine that audio frames will be provided to it in ULAW format.
  *
  * \since 1.8
  */
-int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, format_t format);
+int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format);
 
 /*!
  * \brief Request that the underlying RTP engine make two RTP instances compatible with eachother
@@ -1592,20 +1608,19 @@ int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_in
  * \param instance The RTP instance
  * \param to_endpoint Formats being sent/received towards the endpoint
  * \param to_asterisk Formats being sent/received towards Asterisk
- *
- * \retval supported formats
+ * \param result capabilities structure to store and return supported formats in.
  *
  * Example usage:
  *
  * \code
- * ast_rtp_instance_available_formats(instance, AST_FORMAT_ULAW, AST_FORMAT_SLINEAR);
+ * ast_rtp_instance_available_formats(instance, to_capabilities, from_capabilities, result_capabilities);
  * \endcode
  *
  * This sees if it is possible to have ulaw communicated to the endpoint but signed linear received into Asterisk.
  *
  * \since 1.8
  */
-format_t ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk);
+void ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result);
 
 /*!
  * \brief Indicate to the RTP engine that packets are now expected to be sent/received on the RTP instance
diff --git a/include/asterisk/slin.h b/include/asterisk/slin.h
index 7abfe7fd8fa0179574ef4112531294c6f0e802db..ab7d843abe9647649e363430664e1d08f747882a 100644
--- a/include/asterisk/slin.h
+++ b/include/asterisk/slin.h
@@ -62,7 +62,6 @@ static inline struct ast_frame *slin8_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.datalen = sizeof(ex_slin8) * 2,
 		.samples = ARRAY_LEN(ex_slin8),
 		.mallocd = 0,
@@ -71,6 +70,7 @@ static inline struct ast_frame *slin8_sample(void)
 		.data.ptr = ex_slin8,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
 	return &f;
 }
 
@@ -78,7 +78,6 @@ static inline struct ast_frame *slin16_sample(void)
 {
 	static struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR16,
 		.datalen = sizeof(ex_slin16) * 2,
 		.samples = ARRAY_LEN(ex_slin16),
 		.mallocd = 0,
@@ -87,5 +86,6 @@ static inline struct ast_frame *slin16_sample(void)
 		.data.ptr = ex_slin16,
 	};
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR16, 0);
 	return &f;
 }
diff --git a/include/asterisk/slinfactory.h b/include/asterisk/slinfactory.h
index 78d4321935cee6e61f36ee630c6fa454ac3c08b1..003c6ac282f4cf83587a85e106b88fcdd82e8c46 100644
--- a/include/asterisk/slinfactory.h
+++ b/include/asterisk/slinfactory.h
@@ -24,6 +24,8 @@
 #ifndef _ASTERISK_SLINFACTORY_H
 #define _ASTERISK_SLINFACTORY_H
 
+#include "asterisk/format.h"
+
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
@@ -37,8 +39,8 @@ struct ast_slinfactory {
 	short *offset;                           /*!< Offset into the hold where audio begins */
 	size_t holdlen;                          /*!< Number of samples currently in the hold */
 	unsigned int size;                       /*!< Number of samples currently in the factory */
-	format_t format;                         /*!< Current format the translation path is converting from */
-	format_t output_format;                  /*!< The output format desired */
+	struct ast_format format;                /*!< Current format the translation path is converting from */
+	struct ast_format output_format;         /*!< The output format desired */
 };
 
 /*!
diff --git a/include/asterisk/speech.h b/include/asterisk/speech.h
index cb167d5b529daa796bfcb1e007e3d306c422b36e..5397d8aaadf407969f42e7876a92bb1578b9ffa8 100644
--- a/include/asterisk/speech.h
+++ b/include/asterisk/speech.h
@@ -58,7 +58,7 @@ struct ast_speech {
 	/*! Current state of structure */
 	int state;
 	/*! Expected write format */
-	int format;
+	struct ast_format format;
 	/*! Data for speech engine */
 	void *data;
 	/*! Cached results */
@@ -74,7 +74,7 @@ struct ast_speech_engine {
 	/*! Name of speech engine */
 	char *name;
 	/*! Set up the speech structure within the engine */
-	int (*create)(struct ast_speech *speech, int format);
+	int (*create)(struct ast_speech *speech, struct ast_format *format);
 	/*! Destroy any data set on the speech structure by the engine */
 	int (*destroy)(struct ast_speech *speech);
 	/*! Load a local grammar on the speech structure */
@@ -98,7 +98,7 @@ struct ast_speech_engine {
 	/*! Try to get results */
 	struct ast_speech_result *(*get)(struct ast_speech *speech);
 	/*! Accepted formats by the engine */
-	int formats;
+	struct ast_format_cap *formats;
 	AST_LIST_ENTRY(ast_speech_engine) list;
 };
 
@@ -131,7 +131,7 @@ int ast_speech_results_free(struct ast_speech_result *result);
 /*! \brief Indicate to the speech engine that audio is now going to start being written */
 void ast_speech_start(struct ast_speech *speech);
 /*! \brief Create a new speech structure */
-struct ast_speech *ast_speech_new(const char *engine_name, int formats);
+struct ast_speech *ast_speech_new(const char *engine_name, const struct ast_format_cap *formats);
 /*! \brief Destroy a speech structure */
 int ast_speech_destroy(struct ast_speech *speech);
 /*! \brief Write audio to the speech engine */
diff --git a/include/asterisk/translate.h b/include/asterisk/translate.h
index 821463bf19865d3315cdf9aae4b35636a8f080ea..7e73cd1b199906e9e4f930b42acf222dad8a7c7c 100644
--- a/include/asterisk/translate.h
+++ b/include/asterisk/translate.h
@@ -24,9 +24,6 @@
 #ifndef _ASTERISK_TRANSLATE_H
 #define _ASTERISK_TRANSLATE_H
 
-#define MAX_AUDIO_FORMAT 47 /* Do not include video here */
-#define MAX_FORMAT 64	/* Do include video here */
-
 #if defined(__cplusplus) || defined(c_plusplus)
 extern "C" {
 #endif
@@ -35,11 +32,78 @@ extern "C" {
 #include "asterisk/frame.h"
 #include "asterisk/plc.h"
 #include "asterisk/linkedlists.h"
-// XXX #include "asterisk/module.h"
 #endif
 
 struct ast_trans_pvt;	/* declared below */
 
+/*!
+ * \brief Translator Cost Table definition.
+ *
+ * \note The defined values in this table must be used to set
+ * the translator's table_cost value.
+ *
+ * \note The cost value of the first two values must always add
+ * up to be greater than the largest value defined in this table.
+ * This is done to guarantee a direct translation will always
+ * have precedence over a multi step translation.
+ *
+ * \details This table is built in a way that allows translation
+ * paths to be built that guarantee the best possible balance
+ * between performance and quality.  With this table direct
+ * translation paths between two formats will always take precedence
+ * over multi step paths, lossless intermediate steps will always
+ * be chosen over lossy intermediate steps, and preservation of
+ * sample rate across the translation will always have precedence
+ * over a path that involves any re-sampling.
+ */
+enum ast_trans_cost_table {
+
+	/* Lossless Source Translation Costs */
+
+	/*! [lossless -> lossless] original sampling */
+	AST_TRANS_COST_LL_LL_ORIGSAMP = 400000,
+	/*! [lossless -> lossy]    original sampling */
+	AST_TRANS_COST_LL_LY_ORIGSAMP = 600000,
+
+	/*! [lossless -> lossless] up sample */
+	AST_TRANS_COST_LL_LL_UPSAMP   = 800000,
+	/*! [lossless -> lossy]    up sample */
+	AST_TRANS_COST_LL_LY_UPSAMP   = 825000,
+
+	/*! [lossless -> lossless] down sample */
+	AST_TRANS_COST_LL_LL_DOWNSAMP = 850000,
+	/*! [lossless -> lossy]    down sample */
+	AST_TRANS_COST_LL_LY_DOWNSAMP = 875000,
+
+	/*! [lossless -> unknown]    unknown.
+	 * This value is for a lossless source translation
+	 * with an unknown destination and or sample rate conversion. */
+	AST_TRANS_COST_LL_UNKNOWN     = 885000,
+
+	/* Lossy Source Translation Costs */
+
+	/*! [lossy -> lossless]    original sampling */
+	AST_TRANS_COST_LY_LL_ORIGSAMP = 900000,
+	/*! [lossy -> lossy]       original sampling */
+	AST_TRANS_COST_LY_LY_ORIGSAMP = 915000,
+
+	/*! [lossy -> lossless]    up sample */
+	AST_TRANS_COST_LY_LL_UPSAMP   = 930000,
+	/*! [lossy -> lossy]       up sample */
+	AST_TRANS_COST_LY_LY_UPSAMP   = 945000,
+
+	/*! [lossy -> lossless]    down sample */
+	AST_TRANS_COST_LY_LL_DOWNSAMP = 960000,
+	/*! [lossy -> lossy]       down sample */
+	AST_TRANS_COST_LY_LY_DOWNSAMP = 975000,
+
+	/*! [lossy -> unknown]    unknown.
+	 * This value is for a lossy source translation
+	 * with an unknown destination and or sample rate conversion. */
+	AST_TRANS_COST_LY_UNKNOWN     = 985000,
+
+};
+
 /*! \brief
  * Descriptor of a translator. 
  *
@@ -70,10 +134,14 @@ struct ast_trans_pvt;	/* declared below */
  */
 struct ast_translator {
 	const char name[80];                   /*!< Name of translator */
-	format_t srcfmt;                       /*!< Source format (note: bit position,
-	                                        *   converted to index during registration) */
-	format_t dstfmt;                       /*!< Destination format (note: bit position,
-	                                        *   converted to index during registration) */
+	struct ast_format src_format;          /*!< Source format */
+	struct ast_format dst_format;          /*!< Destination format */
+
+	int table_cost;                        /*!< Cost value associated with this translator based
+	                                        *   on translation cost table. */
+	int comp_cost;                         /*!< Cost value associated with this translator based
+	                                        *   on computation time. This cost value is computed based
+											*   on the time required to translate sample data. */
 
 	int (*newpvt)(struct ast_trans_pvt *); /*!< initialize private data 
                                             *   associated with the translator */
@@ -109,8 +177,9 @@ struct ast_translator {
 
 	struct ast_module *module;             /*!< opaque reference to the parent module */
 
-	int cost;                              /*!< Cost in milliseconds for encoding/decoding 1 second of sound */
 	int active;                            /*!< Whether this translator should be used or not */
+	int src_fmt_index;                     /*!< index of the source format in the matrix table */
+	int dst_fmt_index;                     /*!< index of the destination format in the matrix table */
 	AST_LIST_ENTRY(ast_translator) list;   /*!< link field */
 };
 
@@ -199,11 +268,20 @@ void ast_translator_deactivate(struct ast_translator *t);
  * \brief Chooses the best translation path
  *
  * Given a list of sources, and a designed destination format, which should
- * I choose? 
- * \return Returns 0 on success, -1 if no path could be found.  
- * \note Modifies dests and srcs in place 
+ * I choose?
+ *
+ * \param destination capabilities
+ * \param source capabilities
+ * \param destination format chosen out of destination capabilities
+ * \param source format chosen out of source capabilities
+ * \return Returns 0 on success, -1 if no path could be found.
+ *
+ * \note dst_cap and src_cap are not mondified.
  */
-format_t ast_translator_best_choice(format_t *dsts, format_t *srcs);
+int ast_translator_best_choice(struct ast_format_cap *dst_cap,
+	struct ast_format_cap *src_cap,
+	struct ast_format *dst_fmt_out,
+	struct ast_format *src_fmt_out);
 
 /*! 
  * \brief Builds a translator path
@@ -212,7 +290,7 @@ format_t ast_translator_best_choice(format_t *dsts, format_t *srcs);
  * \param source source format
  * \return ast_trans_pvt on success, NULL on failure
  * */
-struct ast_trans_pvt *ast_translator_build_path(format_t dest, format_t source);
+struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dest, struct ast_format *source);
 
 /*!
  * \brief Frees a translator path
@@ -238,12 +316,14 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *tr, struct ast_frame *f, i
  * \param src source format
  * \return the number of translation steps required, or -1 if no path is available
  */
-unsigned int ast_translate_path_steps(format_t dest, format_t src);
+unsigned int ast_translate_path_steps(struct ast_format *dest, struct ast_format *src);
 
 /*!
- * \brief Mask off unavailable formats from a format bitmask
+ * \brief Find available formats
  * \param dest possible destination formats
  * \param src source formats
+ * \param result capabilities structure to store available formats in
+ *
  * \return the destination formats that are available in the source or translatable
  *
  * The result will include all formats from 'dest' that are either present
@@ -252,7 +332,7 @@ unsigned int ast_translate_path_steps(format_t dest, format_t src);
  * \note Only a single audio format and a single video format can be
  * present in 'src', or the function will produce unexpected results.
  */
-format_t ast_translate_available_formats(format_t dest, format_t src);
+void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result);
 
 /*!
  * \brief Puts a string representation of the translation path into outbuf
@@ -262,6 +342,13 @@ format_t ast_translate_available_formats(format_t dest, format_t src);
  */
 const char *ast_translate_path_to_str(struct ast_trans_pvt *t, struct ast_str **str);
 
+/*!
+ * \brief Initialize the translation matrix and index to format conversion table.
+ * \retval 0 on success
+ * \retval -1 on failure
+ */
+int ast_translate_init(void);
+
 #if defined(__cplusplus) || defined(c_plusplus)
 }
 #endif
diff --git a/main/abstract_jb.c b/main/abstract_jb.c
index 4cd5ccb0d7acaf732d5f98c8361f8b953d6ca168..5ff1c4b2a85c4ed7eebd1a94ff0b490ba3442608 100644
--- a/main/abstract_jb.c
+++ b/main/abstract_jb.c
@@ -398,7 +398,7 @@ static void jb_get_and_deliver(struct ast_channel *chan)
 	}
 
 	while (now >= jb->next) {
-		interpolation_len = ast_codec_interp_len(jb->last_format);
+		interpolation_len = ast_codec_interp_len(&jb->last_format);
 
 		res = jbimpl->get(jbobj, &f, now, interpolation_len);
 
@@ -409,13 +409,13 @@ static void jb_get_and_deliver(struct ast_channel *chan)
 		case JB_IMPL_DROP:
 			jb_framelog("\tJB_GET {now=%ld}: %s frame with ts=%ld and len=%ld\n",
 				now, jb_get_actions[res], f->ts, f->len);
-			jb->last_format = f->subclass.codec;
+			ast_format_copy(&jb->last_format, &f->subclass.format);
 			ast_frfree(f);
 			break;
 		case JB_IMPL_INTERP:
 			/* interpolate a frame */
 			f = &finterp;
-			f->subclass.codec = jb->last_format;
+			ast_format_copy(&f->subclass.format, &jb->last_format);
 			f->samples  = interpolation_len * 8;
 			f->src  = "JB interpolation";
 			f->delivery = ast_tvadd(jb->timebase, ast_samp2tv(jb->next, 1000));
@@ -476,7 +476,7 @@ static int create_jb(struct ast_channel *chan, struct ast_frame *frr)
 	jb->next = jbimpl->next(jbobj);
 
 	/* Init last format for a first time. */
-	jb->last_format = frr->subclass.codec;
+	ast_format_copy(&jb->last_format, &frr->subclass.format);
 
 	/* Create a frame log file */
 	if (ast_test_flag(jbconf, AST_JB_LOG)) {
diff --git a/main/app.c b/main/app.c
index 0054c4cdeb95f4f95c5fca0c76951e9e0a658cba..27858a29b9af891942dd5e01018a5759c5831f8e 100644
--- a/main/app.c
+++ b/main/app.c
@@ -445,15 +445,15 @@ struct linear_state {
 	int fd;
 	int autoclose;
 	int allowoverride;
-	int origwfmt;
+	struct ast_format origwfmt;
 };
 
 static void linear_release(struct ast_channel *chan, void *params)
 {
 	struct linear_state *ls = params;
 
-	if (ls->origwfmt && ast_set_write_format(chan, ls->origwfmt)) {
-		ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, ls->origwfmt);
+	if (ls->origwfmt.id && ast_set_write_format(chan, &ls->origwfmt)) {
+		ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%d'\n", chan->name, ls->origwfmt.id);
 	}
 
 	if (ls->autoclose) {
@@ -469,12 +469,13 @@ static int linear_generator(struct ast_channel *chan, void *data, int len, int s
 	struct linear_state *ls = data;
 	struct ast_frame f = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.data.ptr = buf + AST_FRIENDLY_OFFSET / 2,
 		.offset = AST_FRIENDLY_OFFSET,
 	};
 	int res;
 
+	ast_format_set(&f.subclass.format, AST_FORMAT_SLINEAR, 0);
+
 	len = samples * 2;
 	if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
 		ast_log(LOG_WARNING, "Can't generate %d bytes of data!\n" , len);
@@ -507,9 +508,9 @@ static void *linear_alloc(struct ast_channel *chan, void *params)
 		ast_clear_flag(chan, AST_FLAG_WRITE_INT);
 	}
 
-	ls->origwfmt = chan->writeformat;
+	ast_format_copy(&ls->origwfmt, &chan->writeformat);
 
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to linear format (write)\n", chan->name);
 		ast_free(ls);
 		ls = params = NULL;
@@ -741,10 +742,11 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
 	int totalsilence = 0;
 	int dspsilence = 0;
 	int olddspsilence = 0;
-	int rfmt = 0;
+	struct ast_format rfmt;
 	struct ast_silence_generator *silgen = NULL;
 	char prependfile[80];
 
+	ast_format_clear(&rfmt);
 	if (silencethreshold < 0) {
 		silencethreshold = global_silence_threshold;
 	}
@@ -815,8 +817,8 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
 			return -1;
 		}
 		ast_dsp_set_threshold(sildet, silencethreshold);
-		rfmt = chan->readformat;
-		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		ast_format_copy(&rfmt, &chan->readformat);
+		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
 			ast_dsp_free(sildet);
@@ -1005,8 +1007,8 @@ static int __ast_play_and_record(struct ast_channel *chan, const char *playfile,
 			ast_filedelete(prependfile, sfmt[x]);
 		}
 	}
-	if (rfmt && ast_set_read_format(chan, rfmt)) {
-		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(rfmt), chan->name);
+	if (rfmt.id && ast_set_read_format(chan, &rfmt)) {
+		ast_log(LOG_WARNING, "Unable to restore format %s to channel '%s'\n", ast_getformatname(&rfmt), chan->name);
 	}
 	if (outmsg == 2) {
 		ast_stream_and_wait(chan, "auth-thankyou", "");
diff --git a/main/asterisk.c b/main/asterisk.c
index 8d81b5eedc765b8c35acb51e226a23fa7b238bd2..7f8b6a285aa7f2407b99089cff474afb41ec3c25 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -111,6 +111,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/network.h"
 #include "asterisk/cli.h"
 #include "asterisk/channel.h"
+#include "asterisk/translate.h"
 #include "asterisk/features.h"
 #include "asterisk/ulaw.h"
 #include "asterisk/alaw.h"
@@ -142,6 +143,7 @@ int daemon(int, int);  /* defined in libresolv of all places */
 #include "asterisk/poll-compat.h"
 #include "asterisk/ccss.h"
 #include "asterisk/test.h"
+#include "asterisk/format.h"
 #include "asterisk/aoc.h"
 
 #include "../defaults.h"
@@ -3669,6 +3671,11 @@ int main(int argc, char *argv[])
 	}
 #endif
 
+	if (ast_translate_init()) {
+		printf("%s", term_quit());
+		exit(1);
+	}
+
 	ast_aoc_cli_init();
 
 	ast_makesocket();
@@ -3700,6 +3707,8 @@ int main(int argc, char *argv[])
 
 	astobj2_init();
 
+	ast_format_attr_init();
+
 	ast_autoservice_init();
 
 	if (ast_timing_init()) {
diff --git a/main/astobj2.c b/main/astobj2.c
index ccfbf5388f59d0768d3d882c7bc7524ece6d9f70..6391844fe82ffaf002b12a2399bb116f532060b7 100644
--- a/main/astobj2.c
+++ b/main/astobj2.c
@@ -137,7 +137,7 @@ enum ao2_callback_type {
 static int internal_ao2_ref(void *user_data, const int delta);
 static struct ao2_container *internal_ao2_container_alloc(struct ao2_container *c, const uint n_buckets, ao2_hash_fn *hash_fn,
 							  ao2_callback_fn *cmp_fn);
-static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, const char *file, int line, const char *func);
+static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, int flags, const char *file, int line, const char *func);
 static void *internal_ao2_callback(struct ao2_container *c,
 				   const enum search_flags flags, void *cb_fn, void *arg, void *data, enum ao2_callback_type type,
 				   char *tag, char *file, int line, const char *funcname);
@@ -471,7 +471,7 @@ struct bucket_entry {
  * link an object to a container
  */
 
-static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, const char *file, int line, const char *func)
+static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *user_data, int flags, const char *file, int line, const char *func)
 {
 	int i;
 	/* create a new list entry */
@@ -490,7 +490,9 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use
 
 	i = abs(c->hash_fn(user_data, OBJ_POINTER));
 
-	ao2_lock(c);
+	if (!(flags & OBJ_NOLOCK)) {
+		ao2_lock(c);
+	}
 	i %= c->n_buckets;
 	p->astobj = obj;
 	p->version = ast_atomic_fetchadd_int(&c->version, 1);
@@ -501,24 +503,28 @@ static struct bucket_entry *internal_ao2_link(struct ao2_container *c, void *use
 	return p;
 }
 
-void *__ao2_link_debug(struct ao2_container *c, void *user_data, char *tag, char *file, int line, const char *funcname)
+void *__ao2_link_debug(struct ao2_container *c, void *user_data, int flags, char *tag, char *file, int line, const char *funcname)
 {
-	struct bucket_entry *p = internal_ao2_link(c, user_data, file, line, funcname);
+	struct bucket_entry *p = internal_ao2_link(c, user_data, flags, file, line, funcname);
 
 	if (p) {
 		__ao2_ref_debug(user_data, +1, tag, file, line, funcname);
-		ao2_unlock(c);
+		if (!(flags & OBJ_NOLOCK)) {
+			ao2_unlock(c);
+		}
 	}
 	return p;
 }
 
-void *__ao2_link(struct ao2_container *c, void *user_data)
+void *__ao2_link(struct ao2_container *c, void *user_data, int flags)
 {
-	struct bucket_entry *p = internal_ao2_link(c, user_data, __FILE__, __LINE__, __PRETTY_FUNCTION__);
+	struct bucket_entry *p = internal_ao2_link(c, user_data, flags, __FILE__, __LINE__, __PRETTY_FUNCTION__);
 
 	if (p) {
 		__ao2_ref(user_data, +1);
-		ao2_unlock(c);
+		if (!(flags & OBJ_NOLOCK)) {
+			ao2_unlock(c);
+		}
 	}
 	return p;
 }
@@ -535,23 +541,26 @@ int ao2_match_by_addr(void *user_data, void *arg, int flags)
  * Unlink an object from the container
  * and destroy the associated * bucket_entry structure.
  */
-void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, char *tag,
+void *__ao2_unlink_debug(struct ao2_container *c, void *user_data, int flags, char *tag,
 			 char *file, int line, const char *funcname)
 {
 	if (INTERNAL_OBJ(user_data) == NULL)	/* safety check on the argument */
 		return NULL;
 
-	__ao2_callback_debug(c, OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA, ao2_match_by_addr, user_data, tag, file, line, funcname);
+	flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
+
+	__ao2_callback_debug(c, flags, ao2_match_by_addr, user_data, tag, file, line, funcname);
 
 	return NULL;
 }
 
-void *__ao2_unlink(struct ao2_container *c, void *user_data)
+void *__ao2_unlink(struct ao2_container *c, void *user_data, int flags)
 {
 	if (INTERNAL_OBJ(user_data) == NULL)	/* safety check on the argument */
 		return NULL;
 
-	__ao2_callback(c, OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA, ao2_match_by_addr, user_data);
+	flags |= (OBJ_UNLINK | OBJ_POINTER | OBJ_NODATA);
+	__ao2_callback(c, flags, ao2_match_by_addr, user_data);
 
 	return NULL;
 }
@@ -696,7 +705,7 @@ static void *internal_ao2_callback(struct ao2_container *c,
 			 * link the object into the container that will hold the results.
 			 */
 			if (ret && (multi_container != NULL)) {
-				__ao2_link(multi_container, ret);
+				__ao2_link(multi_container, ret, flags);
 				ret = NULL;
 			}
 
diff --git a/main/audiohook.c b/main/audiohook.c
index ad977ecbc60f31f85350bc508de0b0eaab7e6876..23650a79f83c45908751898db72c4abe08aeefdf 100644
--- a/main/audiohook.c
+++ b/main/audiohook.c
@@ -40,7 +40,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 
 struct ast_audiohook_translate {
 	struct ast_trans_pvt *trans_pvt;
-	format_t format;
+	struct ast_format format;
 };
 
 struct ast_audiohook_list {
@@ -185,11 +185,11 @@ static struct ast_frame *audiohook_read_frame_single(struct ast_audiohook *audio
 	short buf[samples];
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.data.ptr = buf,
 		.datalen = sizeof(buf),
 		.samples = samples,
 	};
+	ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	/* Ensure the factory is able to give us the samples we want */
 	if (samples > ast_slinfactory_available(factory))
@@ -212,11 +212,11 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
 	short buf1[samples], buf2[samples], *read_buf = NULL, *write_buf = NULL, *final_buf = NULL, *data1 = NULL, *data2 = NULL;
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.data.ptr = NULL,
 		.datalen = sizeof(buf1),
 		.samples = samples,
 	};
+	ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	/* Make sure both factories have the required samples */
 	usable_read = (ast_slinfactory_available(&audiohook->read_factory) >= samples ? 1 : 0);
@@ -304,23 +304,24 @@ static struct ast_frame *audiohook_read_frame_both(struct ast_audiohook *audioho
  * \param format Format of frame remote side wants back
  * \return Returns frame on success, NULL on failure
  */
-struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, format_t format)
+struct ast_frame *ast_audiohook_read_frame(struct ast_audiohook *audiohook, size_t samples, enum ast_audiohook_direction direction, struct ast_format *format)
 {
 	struct ast_frame *read_frame = NULL, *final_frame = NULL;
+	struct ast_format tmp_fmt;
 
 	if (!(read_frame = (direction == AST_AUDIOHOOK_DIRECTION_BOTH ? audiohook_read_frame_both(audiohook, samples) : audiohook_read_frame_single(audiohook, samples, direction))))
 		return NULL;
 
 	/* If they don't want signed linear back out, we'll have to send it through the translation path */
-	if (format != AST_FORMAT_SLINEAR) {
+	if (format->id != AST_FORMAT_SLINEAR) {
 		/* Rebuild translation path if different format then previously */
-		if (audiohook->format != format) {
+		if (ast_format_cmp(format, &audiohook->format) == AST_FORMAT_CMP_NOT_EQUAL) {
 			if (audiohook->trans_pvt) {
 				ast_translator_free_path(audiohook->trans_pvt);
 				audiohook->trans_pvt = NULL;
 			}
 			/* Setup new translation path for this format... if we fail we can't very well return signed linear so free the frame and return nothing */
-			if (!(audiohook->trans_pvt = ast_translator_build_path(format, AST_FORMAT_SLINEAR))) {
+			if (!(audiohook->trans_pvt = ast_translator_build_path(format, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0)))) {
 				ast_frfree(read_frame);
 				return NULL;
 			}
@@ -619,17 +620,18 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
 	struct ast_audiohook_translate *out_translate = (direction == AST_AUDIOHOOK_DIRECTION_READ ? &audiohook_list->out_translate[0] : &audiohook_list->out_translate[1]);
 	struct ast_frame *start_frame = frame, *middle_frame = frame, *end_frame = frame;
 	struct ast_audiohook *audiohook = NULL;
+	struct ast_format tmp_fmt;
 	int samples = frame->samples;
 
 	/* ---Part_1. translate start_frame to SLINEAR if necessary. */
 	/* If the frame coming in is not signed linear we have to send it through the in_translate path */
-	if (frame->subclass.codec != AST_FORMAT_SLINEAR) {
-		if (in_translate->format != frame->subclass.codec) {
+	if (frame->subclass.format.id != AST_FORMAT_SLINEAR) {
+		if (ast_format_cmp(&frame->subclass.format, &in_translate->format) == AST_FORMAT_CMP_NOT_EQUAL) {
 			if (in_translate->trans_pvt)
 				ast_translator_free_path(in_translate->trans_pvt);
-			if (!(in_translate->trans_pvt = ast_translator_build_path(AST_FORMAT_SLINEAR, frame->subclass.codec)))
+			if (!(in_translate->trans_pvt = ast_translator_build_path(ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0), &frame->subclass.format)))
 				return frame;
-			in_translate->format = frame->subclass.codec;
+			ast_format_copy(&in_translate->format, &frame->subclass.format);
 		}
 		if (!(middle_frame = ast_translate(in_translate->trans_pvt, frame, 0)))
 			return frame;
@@ -707,16 +709,16 @@ static struct ast_frame *audio_audiohook_write_list(struct ast_channel *chan, st
 	/* ---Part_3: Decide what to do with the end_frame (whether to transcode or not) */
 	if (middle_frame == end_frame) {
 		/* Middle frame was modified and became the end frame... let's see if we need to transcode */
-		if (end_frame->subclass.codec != start_frame->subclass.codec) {
-			if (out_translate->format != start_frame->subclass.codec) {
+		if (ast_format_cmp(&end_frame->subclass.format, &start_frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
+			if (ast_format_cmp(&out_translate->format, &start_frame->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
 				if (out_translate->trans_pvt)
 					ast_translator_free_path(out_translate->trans_pvt);
-				if (!(out_translate->trans_pvt = ast_translator_build_path(start_frame->subclass.codec, AST_FORMAT_SLINEAR))) {
+				if (!(out_translate->trans_pvt = ast_translator_build_path(&start_frame->subclass.format, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0)))) {
 					/* We can't transcode this... drop our middle frame and return the original */
 					ast_frfree(middle_frame);
 					return start_frame;
 				}
-				out_translate->format = start_frame->subclass.codec;
+				ast_format_copy(&out_translate->format, &start_frame->subclass.format);
 			}
 			/* Transcode from our middle (signed linear) frame to new format of the frame that came in */
 			if (!(end_frame = ast_translate(out_translate->trans_pvt, middle_frame, 0))) {
diff --git a/main/bridging.c b/main/bridging.c
index a256cf038a2d05a06d656de6f53559c3f9378947..9de02aa346961ea5be37db8971316d8c16b72c92 100644
--- a/main/bridging.c
+++ b/main/bridging.c
@@ -382,16 +382,12 @@ static void *bridge_thread(void *data)
 }
 
 /*! \brief Helper function used to find the "best" bridge technology given a specified capabilities */
-static struct ast_bridge_technology *find_best_technology(format_t capabilities)
+static struct ast_bridge_technology *find_best_technology(uint32_t capabilities)
 {
 	struct ast_bridge_technology *current = NULL, *best = NULL;
 
 	AST_RWLIST_RDLOCK(&bridge_technologies);
 	AST_RWLIST_TRAVERSE(&bridge_technologies, current, entry) {
-		char tmp1[256], tmp2[256];
-		ast_debug(1, "Bridge technology %s has capabilities %s and we want %s\n", current->name,
-			ast_getformatname_multiple(tmp1, sizeof(tmp1), current->capabilities),
-			ast_getformatname_multiple(tmp2, sizeof(tmp2), capabilities));
 		if (current->suspended) {
 			ast_debug(1, "Bridge technology %s is suspended. Skipping.\n", current->name);
 			continue;
@@ -448,7 +444,7 @@ static void destroy_bridge(void *obj)
 	return;
 }
 
-struct ast_bridge *ast_bridge_new(format_t capabilities, int flags)
+struct ast_bridge *ast_bridge_new(uint32_t capabilities, int flags)
 {
 	struct ast_bridge *bridge = NULL;
 	struct ast_bridge_technology *bridge_technology = NULL;
@@ -470,9 +466,6 @@ struct ast_bridge *ast_bridge_new(format_t capabilities, int flags)
 
 	/* If no bridge technology was found we can't possibly do bridging so fail creation of the bridge */
 	if (!bridge_technology) {
-		char codec_buf[256];
-		ast_debug(1, "Failed to find a bridge technology to satisfy capabilities %s\n",
-			ast_getformatname_multiple(codec_buf, sizeof(codec_buf), capabilities));
 		return NULL;
 	}
 
@@ -503,7 +496,7 @@ struct ast_bridge *ast_bridge_new(format_t capabilities, int flags)
 	return bridge;
 }
 
-int ast_bridge_check(format_t capabilities)
+int ast_bridge_check(uint32_t capabilities)
 {
 	struct ast_bridge_technology *bridge_technology = NULL;
 
@@ -542,47 +535,51 @@ int ast_bridge_destroy(struct ast_bridge *bridge)
 
 static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel)
 {
-	format_t formats[2] = {bridge_channel->chan->readformat, bridge_channel->chan->writeformat};
+	struct ast_format formats[2];
+	ast_format_copy(&formats[0], &bridge_channel->chan->readformat);
+	ast_format_copy(&formats[1], &bridge_channel->chan->writeformat);
 
 	/* Are the formats currently in use something ths bridge can handle? */
-	if (!(bridge->technology->formats & bridge_channel->chan->readformat)) {
-		format_t best_format = ast_best_codec(bridge->technology->formats);
+	if (!ast_format_cap_iscompatible(bridge->technology->format_capabilities, &bridge_channel->chan->readformat)) {
+		struct ast_format best_format;
+		ast_best_codec(bridge->technology->format_capabilities, &best_format);
 
 		/* Read format is a no go... */
 		if (option_debug) {
 			char codec_buf[512];
 			ast_debug(1, "Bridge technology %s wants to read any of formats %s but channel has %s\n", bridge->technology->name,
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
-				ast_getformatname(formats[0]));
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->format_capabilities),
+				ast_getformatname(&formats[0]));
 		}
 		/* Switch read format to the best one chosen */
-		if (ast_set_read_format(bridge_channel->chan, best_format)) {
-			ast_log(LOG_WARNING, "Failed to set channel %s to read format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
+		if (ast_set_read_format(bridge_channel->chan, &best_format)) {
+			ast_log(LOG_WARNING, "Failed to set channel %s to read format %s\n", bridge_channel->chan->name, ast_getformatname(&best_format));
 			return -1;
 		}
-		ast_debug(1, "Bridge %p put channel %s into read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
+		ast_debug(1, "Bridge %p put channel %s into read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(&best_format));
 	} else {
-		ast_debug(1, "Bridge %p is happy that channel %s already has read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[0]));
+		ast_debug(1, "Bridge %p is happy that channel %s already has read format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(&formats[0]));
 	}
 
-	if (!(bridge->technology->formats & formats[1])) {
-		int best_format = ast_best_codec(bridge->technology->formats);
+	if (!ast_format_cap_iscompatible(bridge->technology->format_capabilities, &formats[1])) {
+		struct ast_format best_format;
+		ast_best_codec(bridge->technology->format_capabilities, &best_format);
 
 		/* Write format is a no go... */
 		if (option_debug) {
 			char codec_buf[512];
 			ast_debug(1, "Bridge technology %s wants to write any of formats %s but channel has %s\n", bridge->technology->name,
-				ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->formats),
-				ast_getformatname(formats[1]));
+				ast_getformatname_multiple(codec_buf, sizeof(codec_buf), bridge->technology->format_capabilities),
+				ast_getformatname(&formats[1]));
 		}
 		/* Switch write format to the best one chosen */
-		if (ast_set_write_format(bridge_channel->chan, best_format)) {
-			ast_log(LOG_WARNING, "Failed to set channel %s to write format %s\n", bridge_channel->chan->name, ast_getformatname(best_format));
+		if (ast_set_write_format(bridge_channel->chan, &best_format)) {
+			ast_log(LOG_WARNING, "Failed to set channel %s to write format %s\n", bridge_channel->chan->name, ast_getformatname(&best_format));
 			return -1;
 		}
-		ast_debug(1, "Bridge %p put channel %s into write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(best_format));
+		ast_debug(1, "Bridge %p put channel %s into write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(&best_format));
 	} else {
-		ast_debug(1, "Bridge %p is happy that channel %s already has write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(formats[1]));
+		ast_debug(1, "Bridge %p is happy that channel %s already has write format %s\n", bridge, bridge_channel->chan->name, ast_getformatname(&formats[1]));
 	}
 
 	return 0;
@@ -591,7 +588,7 @@ static int bridge_make_compatible(struct ast_bridge *bridge, struct ast_bridge_c
 /*! \brief Perform the smart bridge operation. Basically sees if a new bridge technology should be used instead of the current one. */
 static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_channel *bridge_channel, int count)
 {
-	format_t new_capabilities = 0;
+	uint32_t new_capabilities = 0;
 	struct ast_bridge_technology *new_technology = NULL, *old_technology = bridge->technology;
 	struct ast_bridge temp_bridge = {
 		.technology = bridge->technology,
@@ -621,9 +618,6 @@ static int smart_bridge_operation(struct ast_bridge *bridge, struct ast_bridge_c
 
 	/* Attempt to find a new bridge technology to satisfy the capabilities */
 	if (!(new_technology = find_best_technology(new_capabilities))) {
-		char codec_buf[256];
-		ast_debug(1, "Smart bridge operation was unable to find new bridge technology with capabilities %s to satisfy bridge %p\n",
-			ast_getformatname_multiple(codec_buf, sizeof(codec_buf), new_capabilities), bridge);
 		return -1;
 	}
 
@@ -873,8 +867,10 @@ static void bridge_channel_dtmf_stream(struct ast_bridge *bridge, struct ast_bri
 /*! \brief Join a channel to a bridge and handle anything the bridge may want us to do */
 static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_channel *bridge_channel)
 {
-	int formats[2] = { bridge_channel->chan->readformat, bridge_channel->chan->writeformat };
+	struct ast_format formats[2];
 	enum ast_bridge_channel_state state;
+	ast_format_copy(&formats[0], &bridge_channel->chan->readformat);
+	ast_format_copy(&formats[1], &bridge_channel->chan->writeformat);
 
 	/* Record the thread that will be the owner of us */
 	bridge_channel->thread = pthread_self();
@@ -975,16 +971,16 @@ static enum ast_bridge_channel_state bridge_channel_join(struct ast_bridge_chann
 	ao2_unlock(bridge_channel->bridge);
 
 	/* Restore original formats of the channel as they came in */
-	if (bridge_channel->chan->readformat != formats[0]) {
-		ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
-		if (ast_set_read_format(bridge_channel->chan, formats[0])) {
-			ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(formats[0]), formats[0]);
+	if (ast_format_cmp(&bridge_channel->chan->readformat, &formats[0]) == AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_debug(1, "Bridge is returning %p to read format %s(%d)\n", bridge_channel, ast_getformatname(&formats[0]), formats[0].id);
+		if (ast_set_read_format(bridge_channel->chan, &formats[0])) {
+			ast_debug(1, "Bridge failed to return channel %p to read format %s(%d)\n", bridge_channel, ast_getformatname(&formats[0]), formats[0].id);
 		}
 	}
-	if (bridge_channel->chan->writeformat != formats[1]) {
-		ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
-		if (ast_set_write_format(bridge_channel->chan, formats[1])) {
-			ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(formats[1]), formats[1]);
+	if (ast_format_cmp(&bridge_channel->chan->writeformat, &formats[1]) == AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_debug(1, "Bridge is returning %p to write format %s(%d)\n", bridge_channel, ast_getformatname(&formats[1]), formats[1].id);
+		if (ast_set_write_format(bridge_channel->chan, &formats[1])) {
+			ast_debug(1, "Bridge failed to return channel %p to write format %s(%d)\n", bridge_channel, ast_getformatname(&formats[1]), formats[1].id);
 		}
 	}
 
diff --git a/main/callerid.c b/main/callerid.c
index ac8fbde8b17541efde2620ec54d028e09ca845be..aa53eb83e0eac802efe72883207dac048722fbe9 100644
--- a/main/callerid.c
+++ b/main/callerid.c
@@ -71,7 +71,7 @@ float casdr1, casdi1, casdr2, casdi2;
 
 #define AST_CALLERID_UNKNOWN	"<unknown>"
 
-static inline void gen_tones(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
+static inline void gen_tones(unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float ddr2, float ddi2, float *cr1, float *ci1, float *cr2, float *ci2)
 {
 	int x;
 	float t;
@@ -93,7 +93,7 @@ static inline void gen_tones(unsigned char *buf, int len, format_t codec, float
 	}
 }
 
-static inline void gen_tone(unsigned char *buf, int len, format_t codec, float ddr1, float ddi1, float *cr1, float *ci1)
+static inline void gen_tone(unsigned char *buf, int len, struct ast_format *codec, float ddr1, float ddi1, float *cr1, float *ci1)
 {
 	int x;
 	float t;
@@ -255,7 +255,7 @@ void callerid_get_dtmf(char *cidstring, char *number, int *flags)
 	}
 }
 
-int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, format_t codec)
+int ast_gen_cas(unsigned char *outbuf, int sendsas, int len, struct ast_format *codec)
 {
 	int pos = 0;
 	int saslen = 2400;
@@ -300,7 +300,7 @@ static unsigned short calc_crc(unsigned short crc, unsigned char data)
    	return crc;
 }
 
-int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, format_t codec)
+int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
 {
 	int mylen = len;
 	int olen;
@@ -539,7 +539,7 @@ int callerid_feed_jp(struct callerid_state *cid, unsigned char *ubuf, int len, f
 }
 
 
-int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, format_t codec)
+int callerid_feed(struct callerid_state *cid, unsigned char *ubuf, int len, struct ast_format *codec)
 {
 	int mylen = len;
 	int olen;
@@ -791,7 +791,7 @@ static int callerid_genmsg(char *msg, int size, const char *number, const char *
 	
 }
 
-int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_t codec,
+int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, struct ast_format *codec,
 			       const char* name, const char* number, int flags)
 {
 	char msg[256];
@@ -879,7 +879,7 @@ int ast_callerid_vmwi_generate(unsigned char *buf, int active, int type, format_
 	return bytes;
 }
 
-int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, format_t codec)
+int callerid_generate(unsigned char *buf, const char *number, const char *name, int flags, int callwaiting, struct ast_format *codec)
 {
 	int bytes = 0;
 	int x, sum;
@@ -1038,7 +1038,7 @@ int ast_callerid_parse(char *instr, char **name, char **location)
 	return 0;
 }
 
-static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, format_t codec)
+static int __ast_callerid_generate(unsigned char *buf, const char *name, const char *number, int callwaiting, struct ast_format *codec)
 {
 	if (ast_strlen_zero(name))
 		name = NULL;
@@ -1047,12 +1047,12 @@ static int __ast_callerid_generate(unsigned char *buf, const char *name, const c
 	return callerid_generate(buf, number, name, 0, callwaiting, codec);
 }
 
-int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
+int ast_callerid_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
 {
 	return __ast_callerid_generate(buf, name, number, 0, codec);
 }
 
-int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, format_t codec)
+int ast_callerid_callwaiting_generate(unsigned char *buf, const char *name, const char *number, struct ast_format *codec)
 {
 	return __ast_callerid_generate(buf, name, number, 1, codec);
 }
diff --git a/main/ccss.c b/main/ccss.c
index 3583e8472b2afa818879808e1775b71f35663220..fc79a01ddbf0265e06924ba0ec04ab1744a35de2 100644
--- a/main/ccss.c
+++ b/main/ccss.c
@@ -2482,19 +2482,30 @@ static void *generic_recall(void *data)
 	struct ast_channel *chan;
 	const char *callback_macro = ast_get_cc_callback_macro(agent->cc_params);
 	unsigned int recall_timer = ast_get_cc_recall_timer(agent->cc_params) * 1000;
+	struct ast_format tmp_fmt;
+	struct ast_format_cap *tmp_cap = ast_format_cap_alloc_nolock();
+
+	if (!tmp_cap) {
+		return NULL;
+	}
 
 	tech = interface;
 	if ((target = strchr(interface, '/'))) {
 		*target++ = '\0';
 	}
-	if (!(chan = ast_request_and_dial(tech, AST_FORMAT_SLINEAR, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
+
+	ast_format_cap_add(tmp_cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
+	if (!(chan = ast_request_and_dial(tech, tmp_cap, NULL, target, recall_timer, &reason, generic_pvt->cid_num, generic_pvt->cid_name))) {
 		/* Hmm, no channel. Sucks for you, bud.
 		 */
 		ast_log_dynamic_level(cc_logger_level, "Core %d: Failed to call back %s for reason %d\n",
 				agent->core_id, agent->device_name, reason);
 		ast_cc_failed(agent->core_id, "Failed to call back device %s/%s", tech, target);
+		ast_format_cap_destroy(tmp_cap);
 		return NULL;
 	}
+	ast_format_cap_destroy(tmp_cap);
+
 	if (!ast_strlen_zero(callback_macro)) {
 		ast_log_dynamic_level(cc_logger_level, "Core %d: There's a callback macro configured for agent %s\n",
 				agent->core_id, agent->device_name);
diff --git a/main/channel.c b/main/channel.c
index 0cabf2d7e073cc6500505646f73687d2712cc1ba..796dc8b011748ef3d7c0ac6f0086282a7f4ae02d 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -372,12 +372,12 @@ int ast_channel_data_add_structure(struct ast_data *tree,
 		}
 	}
 
-	ast_data_add_codecs(tree, "oldwriteformat", chan->oldwriteformat);
+	ast_data_add_codec(tree, "oldwriteformat", &chan->oldwriteformat);
+	ast_data_add_codec(tree, "readformat", &chan->readformat);
+	ast_data_add_codec(tree, "writeformat", &chan->writeformat);
+	ast_data_add_codec(tree, "rawreadformat", &chan->rawreadformat);
+	ast_data_add_codec(tree, "rawwriteformat", &chan->rawwriteformat);
 	ast_data_add_codecs(tree, "nativeformats", chan->nativeformats);
-	ast_data_add_codecs(tree, "readformat", chan->readformat);
-	ast_data_add_codecs(tree, "writeformat", chan->writeformat);
-	ast_data_add_codecs(tree, "rawreadformat", chan->rawreadformat);
-	ast_data_add_codecs(tree, "rawwriteformat", chan->rawwriteformat);
 
 	/* state */
 	enum_node = ast_data_add_node(tree, "state");
@@ -593,7 +593,7 @@ static char *handle_cli_core_show_channeltype(struct ast_cli_entry *e, int cmd,
 		(cl->tech->devicestate) ? "yes" : "no",
 		(cl->tech->indicate) ? "yes" : "no",
 		(cl->tech->transfer) ? "yes" : "no",
-		ast_getformatname_multiple(buf, sizeof(buf), (cl->tech->capabilities) ? cl->tech->capabilities : -1),
+		ast_getformatname_multiple(buf, sizeof(buf), cl->tech->capabilities),
 		(cl->tech->send_digit_begin) ? "yes" : "no",
 		(cl->tech->send_digit_end) ? "yes" : "no",
 		(cl->tech->send_html) ? "yes" : "no",
@@ -989,12 +989,11 @@ char *ast_transfercapability2str(int transfercapability)
 }
 
 /*! \brief Pick the best audio codec */
-format_t ast_best_codec(format_t fmts)
+struct ast_format *ast_best_codec(struct ast_format_cap *cap, struct ast_format *result)
 {
 	/* This just our opinion, expressed in code.  We are asked to choose
 	   the best codec to use, given no information */
-	int x;
-	static const format_t prefs[] =
+	static const enum ast_format_id prefs[] =
 	{
 		/*! Okay, ulaw is used by all telephony equipment, so start with it */
 		AST_FORMAT_ULAW,
@@ -1032,19 +1031,19 @@ format_t ast_best_codec(format_t fmts)
 		AST_FORMAT_G723_1,
 	};
 	char buf[512];
+	int x;
 
-	/* Strip out video */
-	fmts &= AST_FORMAT_AUDIO_MASK;
-	
 	/* Find the first preferred codec in the format given */
 	for (x = 0; x < ARRAY_LEN(prefs); x++) {
-		if (fmts & prefs[x])
-			return prefs[x];
+		if (ast_format_cap_iscompatible(cap, ast_format_set(result, prefs[x], 0))) {
+			return result;
+		}
 	}
 
-	ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), fmts));
+	ast_format_clear(result);
+	ast_log(LOG_WARNING, "Don't know any of %s formats\n", ast_getformatname_multiple(buf, sizeof(buf), cap));
 
-	return 0;
+	return NULL;
 }
 
 static const struct ast_channel_tech null_tech = {
@@ -1087,6 +1086,11 @@ __ast_channel_alloc_ap(int needqueue, int state, const char *cid_num, const char
 		/* Channel structure allocation failure. */
 		return NULL;
 	}
+	if (!(tmp->nativeformats = ast_format_cap_alloc())) {
+		ao2_ref(tmp, -1);
+		/* format capabilities structure allocation failure */
+		return NULL;
+	}
 
 	/*
 	 * Init file descriptors to unopened state so
@@ -2426,6 +2430,8 @@ static void ast_channel_destructor(void *obj)
 		 */
 		ast_devstate_changed_literal(AST_DEVICE_UNKNOWN, device_name);
 	}
+
+	chan->nativeformats = ast_format_cap_destroy(chan->nativeformats);
 }
 
 /*! \brief Free a dummy channel structure */
@@ -2658,8 +2664,15 @@ static void free_translation(struct ast_channel *clonechan)
 		ast_translator_free_path(clonechan->readtrans);
 	clonechan->writetrans = NULL;
 	clonechan->readtrans = NULL;
-	clonechan->rawwriteformat = clonechan->nativeformats;
-	clonechan->rawreadformat = clonechan->nativeformats;
+	if (ast_format_cap_is_empty(clonechan->nativeformats)) {
+		ast_format_clear(&clonechan->rawwriteformat);
+		ast_format_clear(&clonechan->rawreadformat);
+	} else {
+		struct ast_format tmpfmt;
+		ast_best_codec(clonechan->nativeformats, &tmpfmt);
+		ast_format_copy(&clonechan->rawwriteformat, &tmpfmt);
+		ast_format_copy(&clonechan->rawreadformat, &tmpfmt);
+	}
 }
 
 void ast_set_hangupsource(struct ast_channel *chan, const char *source, int force)
@@ -2987,7 +3000,7 @@ static int generator_force(const void *data)
 	if (!tmp || !generate)
 		return 0;
 
-	res = generate(chan, tmp, 0, ast_format_rate(chan->writeformat & AST_FORMAT_AUDIO_MASK) / 50);
+	res = generate(chan, tmp, 0, ast_format_rate(&chan->writeformat) / 50);
 
 	chan->generatordata = tmp;
 
@@ -3548,9 +3561,9 @@ static void ast_read_generator_actions(struct ast_channel *chan, struct ast_fram
 
 		chan->generatordata = NULL;     /* reset, to let writes go through */
 
-		if (f->subclass.codec != chan->writeformat) {
+		if (ast_format_cmp(&f->subclass.format, &chan->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) {
 			float factor;
-			factor = ((float) ast_format_rate(chan->writeformat)) / ((float) ast_format_rate(f->subclass.codec));
+			factor = ((float) ast_format_rate(&chan->writeformat)) / ((float) ast_format_rate(&f->subclass.format));
 			samples = (int) ( ((float) f->samples) * factor );
 		} else {
 			samples = f->samples;
@@ -4066,11 +4079,11 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 					ast_frfree(f);
 					f = &ast_null_frame;
 				}
-			} else if ((f->frametype == AST_FRAME_VOICE) && !(f->subclass.codec & chan->nativeformats)) {
+			} else if ((f->frametype == AST_FRAME_VOICE) && !ast_format_cap_iscompatible(chan->nativeformats, &f->subclass.format)) {
 				/* This frame is not one of the current native formats -- drop it on the floor */
 				char to[200];
 				ast_log(LOG_NOTICE, "Dropping incompatible voice frame on %s of format %s since our native format has changed to %s\n",
-					chan->name, ast_getformatname(f->subclass.codec), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
+					chan->name, ast_getformatname(&f->subclass.format), ast_getformatname_multiple(to, sizeof(to), chan->nativeformats));
 				ast_frfree(f);
 				f = &ast_null_frame;
 			} else if ((f->frametype == AST_FRAME_VOICE)) {
@@ -4086,7 +4099,7 @@ static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
 #ifndef MONITOR_CONSTANT_DELAY
 					int jump = chan->outsmpl - chan->insmpl - 4 * f->samples;
 					if (jump >= 0) {
-						jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
+						jump = calc_monitor_jump((chan->outsmpl - chan->insmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
 						if (ast_seekstream(chan->monitor->read_stream, jump, SEEK_FORCECUR) == -1)
 							ast_log(LOG_WARNING, "Failed to perform seek in monitoring read stream, synchronization between the files may be broken\n");
 						chan->insmpl += (chan->outsmpl - chan->insmpl) + f->samples;
@@ -4557,7 +4570,7 @@ int ast_prod(struct ast_channel *chan)
 	/* Send an empty audio frame to get things moving */
 	if (chan->_state != AST_STATE_UP) {
 		ast_debug(1, "Prodding channel '%s'\n", chan->name);
-		a.subclass.codec = chan->rawwriteformat;
+		ast_format_copy(&a.subclass.format, &chan->rawwriteformat);
 		a.data.ptr = nothing + AST_FRIENDLY_OFFSET;
 		a.src = "ast_prod"; /* this better match check in ast_write */
 		if (ast_write(chan, &a))
@@ -4808,12 +4821,12 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 		if (chan->tech->write == NULL)
 			break;	/*! \todo XXX should return 0 maybe ? */
 
-		if (ast_opt_generic_plc && fr->subclass.codec == AST_FORMAT_SLINEAR) {
+		if (ast_opt_generic_plc && fr->subclass.format.id == AST_FORMAT_SLINEAR) {
 			apply_plc(chan, fr);
 		}
 
 		/* If the frame is in the raw write format, then it's easy... just use the frame - otherwise we will have to translate */
-		if (fr->subclass.codec == chan->rawwriteformat)
+		if (ast_format_cmp(&fr->subclass.format, &chan->rawwriteformat) != AST_FORMAT_CMP_NOT_EQUAL)
 			f = fr;
 		else
 			f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
@@ -4880,7 +4893,7 @@ int ast_write(struct ast_channel *chan, struct ast_frame *fr)
 #ifndef MONITOR_CONSTANT_DELAY
 				int jump = chan->insmpl - chan->outsmpl - 4 * cur->samples;
 				if (jump >= 0) {
-					jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(f->subclass.codec), ast_format_rate(chan->monitor->read_stream->fmt->format));
+					jump = calc_monitor_jump((chan->insmpl - chan->outsmpl), ast_format_rate(&f->subclass.format), ast_format_rate(&chan->monitor->read_stream->fmt->format));
 					if (ast_seekstream(chan->monitor->write_stream, jump, SEEK_FORCECUR) == -1)
 						ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
 					chan->outsmpl += (chan->insmpl - chan->outsmpl) + cur->samples;
@@ -4967,26 +4980,33 @@ done:
 	return res;
 }
 
-static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawformat, format_t *format,
-		      struct ast_trans_pvt **trans, const int direction)
+static int set_format(struct ast_channel *chan,
+	struct ast_format_cap *cap_set,
+	struct ast_format *rawformat,
+	struct ast_format *format,
+	struct ast_trans_pvt **trans,
+	const int direction)
 {
-	format_t native, native_fmt = ast_best_codec(fmt);
+	struct ast_format_cap *cap_native = chan->nativeformats;
+	struct ast_format best_set_fmt;
+	struct ast_format best_native_fmt;
 	int res;
 	char from[200], to[200];
-	
-	/* Make sure we only consider audio */
-	fmt &= AST_FORMAT_AUDIO_MASK;
-	
-	native = chan->nativeformats;
 
-	if (!fmt || !native)	/* No audio requested */
-		return 0;	/* Let's try a call without any sounds (video, text) */
+	ast_best_codec(cap_set, &best_set_fmt);
 
 	/* See if the underlying channel driver is capable of performing transcoding for us */
-	if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &native_fmt, sizeof(int*), 0)) {
+	if (!ast_channel_setoption(chan, direction ? AST_OPTION_FORMAT_WRITE : AST_OPTION_FORMAT_READ, &best_set_fmt, sizeof(best_set_fmt), 0)) {
 		ast_debug(1, "Channel driver natively set channel %s to %s format %s\n", chan->name,
-			  direction ? "write" : "read", ast_getformatname(native_fmt));
-		chan->nativeformats = *rawformat = *format = native_fmt;
+			  direction ? "write" : "read", ast_getformatname(&best_set_fmt));
+
+		ast_format_copy(format, &best_set_fmt);
+		ast_format_copy(rawformat, &best_set_fmt);
+
+		ast_channel_lock(chan);
+		ast_format_cap_set(chan->nativeformats, &best_set_fmt);
+		ast_channel_unlock(chan);
+
 		if (*trans) {
 			ast_translator_free_path(*trans);
 		}
@@ -4995,39 +5015,44 @@ static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawforma
 	}
 
 	/* Find a translation path from the native format to one of the desired formats */
-	if (!direction)
+	if (!direction) {
 		/* reading */
-		res = ast_translator_best_choice(&fmt, &native);
-	else
+		res = ast_translator_best_choice(cap_set, cap_native, &best_set_fmt, &best_native_fmt);
+	} else {
 		/* writing */
-		res = ast_translator_best_choice(&native, &fmt);
+		res = ast_translator_best_choice(cap_native, cap_set, &best_native_fmt, &best_set_fmt);
+	}
 
 	if (res < 0) {
 		ast_log(LOG_WARNING, "Unable to find a codec translation path from %s to %s\n",
-			ast_getformatname_multiple(from, sizeof(from), native),
-			ast_getformatname_multiple(to, sizeof(to), fmt));
+			ast_getformatname_multiple(from, sizeof(from), cap_native),
+			ast_getformatname_multiple(to, sizeof(to), cap_set));
 		return -1;
 	}
-	
+
 	/* Now we have a good choice for both. */
 	ast_channel_lock(chan);
 
-	if ((*rawformat == native) && (*format == fmt) && ((*rawformat == *format) || (*trans))) {
+	if ((ast_format_cmp(rawformat, &best_native_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
+		(ast_format_cmp(format, &best_set_fmt) != AST_FORMAT_CMP_NOT_EQUAL) &&
+		((ast_format_cmp(rawformat, format) != AST_FORMAT_CMP_NOT_EQUAL) || (*trans))) {
 		/* the channel is already in these formats, so nothing to do */
 		ast_channel_unlock(chan);
 		return 0;
 	}
 
-	*rawformat = native;
+	ast_format_copy(rawformat, &best_native_fmt);
 	/* User perspective is fmt */
-	*format = fmt;
+	ast_format_copy(format, &best_set_fmt);
+
 	/* Free any read translation we have right now */
 	if (*trans) {
 		ast_translator_free_path(*trans);
 		*trans = NULL;
 	}
+
 	/* Build a translation path from the raw format to the desired format */
-	if (*format == *rawformat) {
+	if (ast_format_cmp(format, rawformat) != AST_FORMAT_CMP_NOT_EQUAL) {
 		/*
 		 * If we were able to swap the native format to the format that
 		 * has been requested, then there is no need to try to build
@@ -5037,29 +5062,122 @@ static int set_format(struct ast_channel *chan, format_t fmt, format_t *rawforma
 	} else {
 		if (!direction) {
 			/* reading */
-			*trans = ast_translator_build_path(*format, *rawformat);
+			*trans = ast_translator_build_path(format, rawformat);
 		} else {
 			/* writing */
-			*trans = ast_translator_build_path(*rawformat, *format);
+			*trans = ast_translator_build_path(rawformat, format);
 		}
 		res = *trans ? 0 : -1;
 	}
 	ast_channel_unlock(chan);
-	ast_debug(1, "Set channel %s to %s format %s\n", chan->name,
-		direction ? "write" : "read", ast_getformatname(fmt));
+
+	ast_debug(1, "Set channel %s to %s format %s\n",
+		chan->name,
+		direction ? "write" : "read",
+		ast_getformatname(&best_set_fmt));
+	return res;
+}
+
+int ast_set_read_format(struct ast_channel *chan, struct ast_format *format)
+{
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	int res;
+	if (!cap) {
+		return -1;
+	}
+	ast_format_cap_add(cap, format);
+
+	res = set_format(chan,
+		cap,
+		&chan->rawreadformat,
+		&chan->readformat,
+		&chan->readtrans,
+		0);
+
+	ast_format_cap_destroy(cap);
 	return res;
 }
 
-int ast_set_read_format(struct ast_channel *chan, format_t fmt)
+int ast_set_read_format_by_id(struct ast_channel *chan, enum ast_format_id id)
 {
-	return set_format(chan, fmt, &chan->rawreadformat, &chan->readformat,
-			  &chan->readtrans, 0);
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	struct ast_format tmp_format;
+	int res;
+	if (!cap) {
+		return -1;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
+
+	res = set_format(chan,
+		cap,
+		&chan->rawreadformat,
+		&chan->readformat,
+		&chan->readtrans,
+		0);
+
+	ast_format_cap_destroy(cap);
+	return res;
 }
 
-int ast_set_write_format(struct ast_channel *chan, format_t fmt)
+int ast_set_read_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
 {
-	return set_format(chan, fmt, &chan->rawwriteformat, &chan->writeformat,
-			  &chan->writetrans, 1);
+	return set_format(chan,
+		cap,
+		&chan->rawreadformat,
+		&chan->readformat,
+		&chan->readtrans,
+		0);
+}
+
+int ast_set_write_format(struct ast_channel *chan, struct ast_format *format)
+{
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	int res;
+	if (!cap) {
+		return -1;
+	}
+	ast_format_cap_add(cap, format);
+
+	res = set_format(chan,
+		cap,
+		&chan->rawwriteformat,
+		&chan->writeformat,
+		&chan->writetrans,
+		1);
+
+	ast_format_cap_destroy(cap);
+	return res;
+}
+
+int ast_set_write_format_by_id(struct ast_channel *chan, enum ast_format_id id)
+{
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	struct ast_format tmp_format;
+	int res;
+	if (!cap) {
+		return -1;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmp_format, id, 0));
+
+	res = set_format(chan,
+		cap,
+		&chan->rawwriteformat,
+		&chan->writeformat,
+		&chan->writetrans,
+		1);
+
+	ast_format_cap_destroy(cap);
+	return res;
+}
+
+int ast_set_write_format_from_cap(struct ast_channel *chan, struct ast_format_cap *cap)
+{
+	return set_format(chan,
+		cap,
+		&chan->rawwriteformat,
+		&chan->writeformat,
+		&chan->writetrans,
+		1);
 }
 
 const char *ast_channel_reason2str(int reason)
@@ -5098,7 +5216,7 @@ static void handle_cause(int cause, int *outstate)
 	}
 }
 
-struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, format_t format, struct outgoing_helper *oh, int *outstate)
+struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_channel *orig, int *timeout, struct ast_format_cap *cap, struct outgoing_helper *oh, int *outstate)
 {
 	char tmpchan[256];
 	struct ast_channel *new = NULL;
@@ -5121,7 +5239,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
 		data = tmpchan;
 		type = "Local";
 	}
-	if (!(new = ast_request(type, format, orig, data, &cause))) {
+	if (!(new = ast_request(type, cap, orig, data, &cause))) {
 		ast_log(LOG_NOTICE, "Unable to create channel for call forward to '%s/%s' (cause = %d)\n", type, data, cause);
 		handle_cause(cause, outstate);
 		ast_hangup(orig);
@@ -5179,7 +5297,7 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan
 	return new;
 }
 
-struct ast_channel *__ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
+struct ast_channel *__ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
 {
 	int dummy_outstate;
 	int cause = 0;
@@ -5193,7 +5311,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co
 	else
 		outstate = &dummy_outstate;	/* make outstate always a valid pointer */
 
-	chan = ast_request(type, format, requestor, data, &cause);
+	chan = ast_request(type, cap, requestor, data, &cause);
 	if (!chan) {
 		ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
 		handle_cause(cause, outstate);
@@ -5245,7 +5363,7 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co
 			if (timeout > -1)
 				timeout = res;
 			if (!ast_strlen_zero(chan->call_forward)) {
-				if (!(chan = ast_call_forward(NULL, chan, NULL, format, oh, outstate))) {
+				if (!(chan = ast_call_forward(NULL, chan, NULL, cap, oh, outstate))) {
 					return NULL;
 				}
 				continue;
@@ -5338,9 +5456,9 @@ struct ast_channel *__ast_request_and_dial(const char *type, format_t format, co
 	return chan;
 }
 
-struct ast_channel *ast_request_and_dial(const char *type, format_t format, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
+struct ast_channel *ast_request_and_dial(const char *type, struct ast_format_cap *cap, const struct ast_channel *requestor, void *data, int timeout, int *outstate, const char *cidnum, const char *cidname)
 {
-	return __ast_request_and_dial(type, format, requestor, data, timeout, outstate, cidnum, cidname, NULL);
+	return __ast_request_and_dial(type, cap, requestor, data, timeout, outstate, cidnum, cidname, NULL);
 }
 
 static int set_security_requirements(const struct ast_channel *requestor, struct ast_channel *out)
@@ -5383,16 +5501,12 @@ static int set_security_requirements(const struct ast_channel *requestor, struct
 	return 0;
 }
 
-struct ast_channel *ast_request(const char *type, format_t format, const struct ast_channel *requestor, void *data, int *cause)
+struct ast_channel *ast_request(const char *type, struct ast_format_cap *request_cap, const struct ast_channel *requestor, void *data, int *cause)
 {
 	struct chanlist *chan;
 	struct ast_channel *c;
-	format_t capabilities;
-	format_t fmt;
 	int res;
 	int foo;
-	format_t videoformat = format & AST_FORMAT_VIDEO_MASK;
-	format_t textformat = format & AST_FORMAT_TEXT_MASK;
 
 	if (!cause)
 		cause = &foo;
@@ -5404,21 +5518,27 @@ struct ast_channel *ast_request(const char *type, format_t format, const struct
 	}
 
 	AST_RWLIST_TRAVERSE(&backends, chan, list) {
+		struct ast_format_cap *tmp_cap;
+		struct ast_format tmp_fmt;
+		struct ast_format best_audio_fmt;
+		struct ast_format_cap *joint_cap;
+
 		if (strcasecmp(type, chan->tech->type))
 			continue;
 
-		capabilities = chan->tech->capabilities;
-		fmt = format & AST_FORMAT_AUDIO_MASK;
-		if (fmt) {
+		ast_format_clear(&best_audio_fmt);
+		/* find the best audio format to use */
+		if ((tmp_cap = ast_format_cap_get_type(request_cap, AST_FORMAT_TYPE_AUDIO))) {
 			/* We have audio - is it possible to connect the various calls to each other? 
 				(Avoid this check for calls without audio, like text+video calls)
 			*/
-			res = ast_translator_best_choice(&fmt, &capabilities);
+			res = ast_translator_best_choice(tmp_cap, chan->tech->capabilities, &tmp_fmt, &best_audio_fmt);
+			ast_format_cap_destroy(tmp_cap);
 			if (res < 0) {
 				char tmp1[256], tmp2[256];
 				ast_log(LOG_WARNING, "No translator path exists for channel type %s (native %s) to %s\n", type,
 					ast_getformatname_multiple(tmp1, sizeof(tmp1), chan->tech->capabilities),
-					ast_getformatname_multiple(tmp2, sizeof(tmp2), format));
+					ast_getformatname_multiple(tmp2, sizeof(tmp2), request_cap));
 				*cause = AST_CAUSE_BEARERCAPABILITY_NOTAVAIL;
 				AST_RWLIST_UNLOCK(&backends);
 				return NULL;
@@ -5428,8 +5548,21 @@ struct ast_channel *ast_request(const char *type, format_t format, const struct
 		if (!chan->tech->requester)
 			return NULL;
 
-		if (!(c = chan->tech->requester(type, capabilities | videoformat | textformat, requestor, data, cause)))
+		/* XXX Only the audio format calculated as being the best for translation
+		 * purposes is used for the request. This needs to be re-evaluated.  It may be
+		 * a better choice to send all the audio formats capable of being translated
+		 * during the request and allow the channel drivers to pick the best one. */
+		if (!(joint_cap = ast_format_cap_dup(request_cap))) {
 			return NULL;
+		}
+		ast_format_cap_remove_bytype(joint_cap, AST_FORMAT_TYPE_AUDIO);
+		ast_format_cap_add(joint_cap, &best_audio_fmt);
+
+		if (!(c = chan->tech->requester(type, joint_cap, requestor, data, cause))) {
+			ast_format_cap_destroy(joint_cap);
+			return NULL;
+		}
+		joint_cap = ast_format_cap_destroy(joint_cap);
 
 		if (set_security_requirements(requestor, c)) {
 			ast_log(LOG_WARNING, "Setting security requirements failed\n");
@@ -5610,7 +5743,10 @@ int ast_channel_sendurl(struct ast_channel *chan, const char *url)
 /*! \brief Set up translation from one channel to another */
 static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
 {
-	format_t src, dst;
+	struct ast_format_cap *src_cap = from->nativeformats; /* shallow copy, do not destroy */
+	struct ast_format_cap *dst_cap = to->nativeformats;   /* shallow copy, do not destroy */
+	struct ast_format best_src_fmt;
+	struct ast_format best_dst_fmt;
 	int use_slin;
 
 	/* See if the channel driver can natively make these two channels compatible */
@@ -5619,20 +5755,17 @@ static int ast_channel_make_compatible_helper(struct ast_channel *from, struct a
 		return 0;
 	}
 
-	if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
+	if ((ast_format_cmp(&from->readformat, &to->writeformat) != AST_FORMAT_CMP_NOT_EQUAL) &&
+		(ast_format_cmp(&to->readformat, &from->writeformat) != AST_FORMAT_CMP_NOT_EQUAL)) {
 		/* Already compatible!  Moving on ... */
 		return 0;
 	}
 
-	/* Set up translation from the 'from' channel to the 'to' channel */
-	src = from->nativeformats;
-	dst = to->nativeformats;
-
 	/* If there's no audio in this call, don't bother with trying to find a translation path */
-	if ((src & AST_FORMAT_AUDIO_MASK) == 0 || (dst & AST_FORMAT_AUDIO_MASK) == 0)
+	if (!ast_format_cap_has_type(src_cap, AST_FORMAT_TYPE_AUDIO) || !ast_format_cap_has_type(dst_cap, AST_FORMAT_TYPE_AUDIO))
 		return 0;
 
-	if (ast_translator_best_choice(&dst, &src) < 0) {
+	if (ast_translator_best_choice(dst_cap, src_cap, &best_src_fmt, &best_dst_fmt) < 0) {
 		ast_log(LOG_WARNING, "No path to translate from %s to %s\n", from->name, to->name);
 		return -1;
 	}
@@ -5643,16 +5776,20 @@ static int ast_channel_make_compatible_helper(struct ast_channel *from, struct a
 	 * no direct conversion available. If generic PLC is
 	 * desired, then transcoding via SLINEAR is a requirement
 	 */
-	use_slin = (src == AST_FORMAT_SLINEAR || dst == AST_FORMAT_SLINEAR);
-	if ((src != dst) && (ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
-	    (ast_translate_path_steps(dst, src) != 1 || use_slin))
-		dst = AST_FORMAT_SLINEAR;
-	if (ast_set_read_format(from, dst) < 0) {
-		ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(dst));
+	use_slin = (best_src_fmt.id == AST_FORMAT_SLINEAR || best_dst_fmt.id == AST_FORMAT_SLINEAR);
+	if ((ast_format_cmp(&best_src_fmt, &best_dst_fmt) == AST_FORMAT_CMP_NOT_EQUAL) &&
+		(ast_opt_generic_plc || ast_opt_transcode_via_slin) &&
+	    (ast_translate_path_steps(&best_dst_fmt, &best_src_fmt) != 1 || use_slin)) {
+
+		ast_format_set(&best_dst_fmt, AST_FORMAT_SLINEAR, 0);
+	}
+
+	if (ast_set_read_format(from, &best_dst_fmt) < 0) {
+		ast_log(LOG_WARNING, "Unable to set read format on channel %s to %s\n", from->name, ast_getformatname(&best_dst_fmt));
 		return -1;
 	}
-	if (ast_set_write_format(to, dst) < 0) {
-		ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(dst));
+	if (ast_set_write_format(to, &best_dst_fmt) < 0) {
+		ast_log(LOG_WARNING, "Unable to set write format on channel %s to %s\n", to->name, ast_getformatname(&best_dst_fmt));
 		return -1;
 	}
 	return 0;
@@ -6199,8 +6336,7 @@ static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer
  */
 int ast_do_masquerade(struct ast_channel *original)
 {
-	format_t x;
-	int i;
+	int x, i;
 	int res=0;
 	int origstate;
 	int visible_indication;
@@ -6218,13 +6354,17 @@ int ast_do_masquerade(struct ast_channel *original)
 	struct ast_cdr *cdr;
 	struct ast_datastore *xfer_ds;
 	struct xfer_masquerade_ds *xfer_colp;
-	format_t rformat = original->readformat;
-	format_t wformat = original->writeformat;
+	struct ast_format rformat;
+	struct ast_format wformat;
+	struct ast_format tmp_format;
 	char newn[AST_CHANNEL_NAME];
 	char orig[AST_CHANNEL_NAME];
 	char masqn[AST_CHANNEL_NAME];
 	char zombn[AST_CHANNEL_NAME];
 
+	ast_format_copy(&rformat, &original->readformat);
+	ast_format_copy(&wformat, &original->writeformat);
+
 	/* XXX This operation is a bit odd.  We're essentially putting the guts of
 	 * the clone channel into the original channel.  Start by killing off the
 	 * original channel's backend.  While the features are nice, which is the
@@ -6383,12 +6523,13 @@ int ast_do_masquerade(struct ast_channel *original)
 	}
 
 	/* Swap the raw formats */
-	x = original->rawreadformat;
-	original->rawreadformat = clonechan->rawreadformat;
-	clonechan->rawreadformat = x;
-	x = original->rawwriteformat;
-	original->rawwriteformat = clonechan->rawwriteformat;
-	clonechan->rawwriteformat = x;
+	ast_format_copy(&tmp_format, &original->rawreadformat);
+	ast_format_copy(&original->rawreadformat, &clonechan->rawreadformat);
+	ast_format_copy(&clonechan->rawreadformat, &tmp_format);
+
+	ast_format_copy(&tmp_format, &original->rawwriteformat);
+	ast_format_copy(&original->rawwriteformat, &clonechan->rawwriteformat);
+	ast_format_copy(&clonechan->rawwriteformat, &tmp_format);
 
 	clonechan->_softhangup = AST_SOFTHANGUP_DEV;
 
@@ -6486,16 +6627,16 @@ int ast_do_masquerade(struct ast_channel *original)
 	ast_channel_set_fd(original, AST_TIMING_FD, original->timingfd);
 
 	/* Our native formats are different now */
-	original->nativeformats = clonechan->nativeformats;
+	ast_format_cap_copy(original->nativeformats, clonechan->nativeformats);
 
 	/* Context, extension, priority, app data, jump table,  remain the same */
 	/* pvt switches.  pbx stays the same, as does next */
 
 	/* Set the write format */
-	ast_set_write_format(original, wformat);
+	ast_set_write_format(original, &wformat);
 
 	/* Set the read format */
-	ast_set_read_format(original, rformat);
+	ast_set_read_format(original, &rformat);
 
 	/* Copy the music class */
 	ast_string_field_set(original, musicclass, clonechan->musicclass);
@@ -6509,7 +6650,7 @@ int ast_do_masquerade(struct ast_channel *original)
 	}
 
 	ast_debug(1, "Putting channel %s in %s/%s formats\n", original->name,
-		ast_getformatname(wformat), ast_getformatname(rformat));
+		ast_getformatname(&wformat), ast_getformatname(&rformat));
 
 	/* Okay.  Last thing is to let the channel driver know about all this mess, so he
 	   can fix up everything as best as possible */
@@ -6753,8 +6894,8 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
 	struct ast_channel *cs[3];
 	struct ast_frame *f;
 	enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
-	format_t o0nativeformats;
-	format_t o1nativeformats;
+	struct ast_format_cap *o0nativeformats;
+	struct ast_format_cap *o1nativeformats;
 	int watch_c0_dtmf;
 	int watch_c1_dtmf;
 	void *pvt0, *pvt1;
@@ -6762,13 +6903,20 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
 	int frame_put_in_jb = 0;
 	int jb_in_use;
 	int to;
-	
+
+	o0nativeformats = ast_format_cap_dup(c0->nativeformats);
+	o1nativeformats = ast_format_cap_dup(c1->nativeformats);
+
+	if (!o0nativeformats || !o1nativeformats) {
+		ast_format_cap_destroy(o0nativeformats); /* NULL safe */
+		ast_format_cap_destroy(o1nativeformats); /* NULL safe */
+		return AST_BRIDGE_FAILED;
+	}
+
 	cs[0] = c0;
 	cs[1] = c1;
 	pvt0 = c0->tech_pvt;
 	pvt1 = c1->tech_pvt;
-	o0nativeformats = c0->nativeformats;
-	o1nativeformats = c1->nativeformats;
 	watch_c0_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_0;
 	watch_c1_dtmf = config->flags & AST_BRIDGE_DTMF_CHANNEL_1;
 
@@ -6790,8 +6938,8 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
 		struct ast_channel *who, *other;
 
 		if ((c0->tech_pvt != pvt0) || (c1->tech_pvt != pvt1) ||
-		    (o0nativeformats != c0->nativeformats) ||
-		    (o1nativeformats != c1->nativeformats)) {
+		    (!ast_format_cap_identical(o0nativeformats, c0->nativeformats)) ||
+		    (!ast_format_cap_identical(o1nativeformats, c1->nativeformats))) {
 			/* Check for Masquerade, codec changes, etc */
 			res = AST_BRIDGE_RETRY;
 			break;
@@ -6941,6 +7089,9 @@ static enum ast_bridge_result ast_generic_bridge(struct ast_channel *c0, struct
 
 	ast_poll_channel_del(c0, c1);
 
+	ast_format_cap_destroy(o0nativeformats);
+	ast_format_cap_destroy(o1nativeformats);
+
 	return res;
 }
 
@@ -7050,8 +7201,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 {
 	struct ast_channel *chans[2] = { c0, c1 };
 	enum ast_bridge_result res = AST_BRIDGE_COMPLETE;
-	format_t o0nativeformats;
-	format_t o1nativeformats;
+	struct ast_format_cap *o0nativeformats;
+	struct ast_format_cap *o1nativeformats;
 	long time_left_ms=0;
 	char caller_warning = 0;
 	char callee_warning = 0;
@@ -7072,6 +7223,16 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 	    ast_test_flag(c1, AST_FLAG_ZOMBIE) || ast_check_hangup_locked(c1))
 		return -1;
 
+	o0nativeformats = ast_format_cap_dup(c0->nativeformats);
+	o1nativeformats = ast_format_cap_dup(c1->nativeformats);
+	if (!o0nativeformats || !o1nativeformats) {
+		ast_format_cap_destroy(o0nativeformats);
+		ast_format_cap_destroy(o1nativeformats);
+		ast_log(LOG_WARNING, "failed to copy native formats\n");
+		return -1;
+	}
+
+
 	*fo = NULL;
 
 	if (ast_tvzero(config->start_time)) {
@@ -7092,9 +7253,6 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 
 	ast_set_owners_and_peers(c0, c1);
 
-	o0nativeformats = c0->nativeformats;
-	o1nativeformats = c1->nativeformats;
-
 	if (config->feature_timer && !ast_tvzero(config->nexteventts)) {
 		config->nexteventts = ast_tvadd(config->feature_start_time, ast_samp2tv(config->feature_timer, 1000));
 	} else if (config->timelimit) {
@@ -7245,6 +7403,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 
 				c0->_bridge = NULL;
 				c1->_bridge = NULL;
+				ast_format_cap_destroy(o0nativeformats);
+				ast_format_cap_destroy(o1nativeformats);
 				return res;
 			} else {
 				ast_clear_flag(c0, AST_FLAG_NBRIDGE);
@@ -7264,16 +7424,21 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 			}
 		}
 
-		if (((c0->writeformat != c1->readformat) || (c0->readformat != c1->writeformat) ||
-		    (c0->nativeformats != o0nativeformats) || (c1->nativeformats != o1nativeformats)) &&
+		if (((ast_format_cmp(&c1->readformat, &c0->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
+			(ast_format_cmp(&c0->readformat, &c1->writeformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
+		    !ast_format_cap_identical(c0->nativeformats, o0nativeformats) ||
+			!ast_format_cap_identical(c1->nativeformats, o1nativeformats)) &&
 		    !(c0->generator || c1->generator)) {
 			if (ast_channel_make_compatible(c0, c1)) {
 				ast_log(LOG_WARNING, "Can't make %s and %s compatible\n", c0->name, c1->name);
 				manager_bridge_event(0, 1, c0, c1);
+				ast_format_cap_destroy(o0nativeformats);
+				ast_format_cap_destroy(o1nativeformats);
 				return AST_BRIDGE_FAILED;
 			}
-			o0nativeformats = c0->nativeformats;
-			o1nativeformats = c1->nativeformats;
+
+			ast_format_cap_copy(o0nativeformats, c0->nativeformats);
+			ast_format_cap_copy(o1nativeformats, c1->nativeformats);
 		}
 
 		update_bridge_vars(c0, c1);
@@ -7310,6 +7475,8 @@ enum ast_bridge_result ast_channel_bridge(struct ast_channel *c0, struct ast_cha
 		S_COR(c1->caller.id.number.valid, c1->caller.id.number.str, "<unknown>"));
 	ast_debug(1, "Bridge stops bridging channels %s and %s\n", c0->name, c1->name);
 
+	ast_format_cap_destroy(o0nativeformats);
+	ast_format_cap_destroy(o1nativeformats);
 	return res;
 }
 
@@ -7356,7 +7523,7 @@ struct tonepair_state {
 	int v1_2;
 	int v2_2;
 	int v3_2;
-	format_t origwfmt;
+	struct ast_format origwfmt;
 	int pos;
 	int duration;
 	int modulate;
@@ -7370,7 +7537,7 @@ static void tonepair_release(struct ast_channel *chan, void *params)
 	struct tonepair_state *ts = params;
 
 	if (chan)
-		ast_set_write_format(chan, ts->origwfmt);
+		ast_set_write_format(chan, &ts->origwfmt);
 	ast_free(ts);
 }
 
@@ -7381,8 +7548,8 @@ static void *tonepair_alloc(struct ast_channel *chan, void *params)
 
 	if (!(ts = ast_calloc(1, sizeof(*ts))))
 		return NULL;
-	ts->origwfmt = chan->writeformat;
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
+	ast_format_copy(&ts->origwfmt, &chan->writeformat);
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
 		tonepair_release(NULL, ts);
 		ts = NULL;
@@ -7436,7 +7603,7 @@ static int tonepair_generator(struct ast_channel *chan, void *data, int len, int
  			ts->data[x] = ts->v3_1 + ts->v3_2; 
  	}
 	ts->f.frametype = AST_FRAME_VOICE;
-	ts->f.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&ts->f.subclass.format, AST_FORMAT_SLINEAR, 0);
 	ts->f.datalen = len;
 	ts->f.samples = samples;
 	ts->f.offset = AST_FRIENDLY_OFFSET;
@@ -7778,11 +7945,11 @@ static int silence_generator_generate(struct ast_channel *chan, void *data, int
 	short buf[samples];
 	struct ast_frame frame = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.data.ptr = buf,
 		.samples = samples,
 		.datalen = sizeof(buf),
 	};
+	ast_format_set(&frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	memset(buf, 0, sizeof(buf));
 
@@ -7799,7 +7966,7 @@ static struct ast_generator silence_generator = {
 };
 
 struct ast_silence_generator {
-	int old_write_format;
+	struct ast_format old_write_format;
 };
 
 struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_channel *chan)
@@ -7810,9 +7977,9 @@ struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_cha
 		return NULL;
 	}
 
-	state->old_write_format = chan->writeformat;
+	ast_format_copy(&state->old_write_format, &chan->writeformat);
 
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 		ast_log(LOG_ERROR, "Could not set write format to SLINEAR\n");
 		ast_free(state);
 		return NULL;
@@ -7834,7 +8001,7 @@ void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_sil
 
 	ast_debug(1, "Stopped silence generator on '%s'\n", chan->name);
 
-	if (ast_set_write_format(chan, state->old_write_format) < 0)
+	if (ast_set_write_format(chan, &state->old_write_format) < 0)
 		ast_log(LOG_ERROR, "Could not return write format to its original state\n");
 
 	ast_free(state);
diff --git a/main/cli.c b/main/cli.c
index 7f4c1791fd76fb2bd883806e869b5163ebccad22..671a2bac77ee3055c3b9942e1aecc21df20c7727 100644
--- a/main/cli.c
+++ b/main/cli.c
@@ -1387,7 +1387,7 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
 	struct timeval now;
 	struct ast_str *out = ast_str_thread_get(&ast_str_thread_global_buf, 16);
 	char cdrtime[256];
-	char nf[256], wf[256], rf[256];
+	char nf[256];
 	struct ast_str *write_transpath = ast_str_alloca(256);
 	struct ast_str *read_transpath = ast_str_alloca(256);
 	long elapsed_seconds=0;
@@ -1469,9 +1469,9 @@ static char *handle_showchan(struct ast_cli_entry *e, int cmd, struct ast_cli_ar
 		S_OR(c->dialed.number.str, "(N/A)"),
 		c->language,	
 		ast_state2str(c->_state), c->_state, c->rings, 
-		ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats), 
-		ast_getformatname_multiple(wf, sizeof(wf), c->writeformat), 
-		ast_getformatname_multiple(rf, sizeof(rf), c->readformat),
+		ast_getformatname_multiple(nf, sizeof(nf), c->nativeformats),
+		ast_getformatname(&c->writeformat),
+		ast_getformatname(&c->readformat),
 		c->writetrans ? "Yes" : "No",
 		ast_translate_path_to_str(c->writetrans, &write_transpath),
 		c->readtrans ? "Yes" : "No",
diff --git a/main/data.c b/main/data.c
index 3b2c124abcf24f0d62f8f23a46a4f07567e6dff3..3ca2f7c27d154d668714189a928428ea2d0a7c1a 100644
--- a/main/data.c
+++ b/main/data.c
@@ -3100,7 +3100,7 @@ static int manager_data_get(struct mansession *s, const struct message *m)
 	return RESULT_SUCCESS;
 }
 
-int ast_data_add_codecs(struct ast_data *root, const char *node_name, format_t capability)
+int ast_data_add_codec(struct ast_data *root, const char *node_name, struct ast_format *format)
 {
 	struct ast_data *codecs, *codec;
 	size_t fmlist_size;
@@ -3113,7 +3113,36 @@ int ast_data_add_codecs(struct ast_data *root, const char *node_name, format_t c
 	}
 	fmlist = ast_get_format_list(&fmlist_size);
 	for (x = 0; x < fmlist_size; x++) {
-		if (fmlist[x].bits & capability) {
+		if (fmlist[x].id == format->id) {
+			codec = ast_data_add_node(codecs, "codec");
+			if (!codec) {
+				return -1;
+			}
+			ast_data_add_str(codec, "name", fmlist[x].name);
+			ast_data_add_int(codec, "samplespersecond", fmlist[x].samplespersecond);
+			ast_data_add_str(codec, "description", fmlist[x].desc);
+			ast_data_add_int(codec, "frame_length", fmlist[x].fr_len);
+		}
+	}
+
+	return 0;
+}
+
+int ast_data_add_codecs(struct ast_data *root, const char *node_name, struct ast_format_cap *cap)
+{
+	struct ast_data *codecs, *codec;
+	size_t fmlist_size;
+	const struct ast_format_list *fmlist;
+	struct ast_format tmp_fmt;
+	int x;
+
+	codecs = ast_data_add_node(root, node_name);
+	if (!codecs) {
+		return -1;
+	}
+	fmlist = ast_get_format_list(&fmlist_size);
+	for (x = 0; x < fmlist_size; x++) {
+		if (ast_format_cap_iscompatible(cap, ast_format_set(&tmp_fmt, fmlist[x].id, 0))) {
 			codec = ast_data_add_node(codecs, "codec");
 			if (!codec) {
 				return -1;
diff --git a/main/dial.c b/main/dial.c
index ba1a2bb53cf3d2c54c54dd5b0b7f9422b5bb74a8..5c30e287dc4ce44cab72dc0d822b8e998dffd1d6 100644
--- a/main/dial.c
+++ b/main/dial.c
@@ -248,13 +248,27 @@ static int begin_dial_channel(struct ast_dial_channel *channel, struct ast_chann
 {
 	char numsubst[AST_MAX_EXTENSION];
 	int res = 1;
+	struct ast_format_cap *cap_all_audio = NULL;
+	struct ast_format_cap *cap_request;
 
 	/* Copy device string over */
 	ast_copy_string(numsubst, channel->device, sizeof(numsubst));
 
+	if (chan) {
+		cap_request = chan->nativeformats;
+	} else {
+		cap_all_audio = ast_format_cap_alloc_nolock();
+		ast_format_cap_add_all_by_type(cap_all_audio, AST_FORMAT_TYPE_AUDIO);
+		cap_request = cap_all_audio;
+	}
+
 	/* If we fail to create our owner channel bail out */
-	if (!(channel->owner = ast_request(channel->tech, chan ? chan->nativeformats : AST_FORMAT_AUDIO_MASK, chan, numsubst, &channel->cause)))
+	if (!(channel->owner = ast_request(channel->tech, cap_request, chan, numsubst, &channel->cause))) {
+		cap_all_audio = ast_format_cap_destroy(cap_all_audio);
 		return -1;
+	}
+	cap_request = NULL;
+	cap_all_audio = ast_format_cap_destroy(cap_all_audio);
 
 	channel->owner->appl = "AppDial2";
 	channel->owner->data = "(Outgoing Line)";
diff --git a/main/dsp.c b/main/dsp.c
index cba01b5f1798b02eb73b845d4e7063b398d71647..69989afe8530d930adde1da20a1b7027038f0053 100644
--- a/main/dsp.c
+++ b/main/dsp.c
@@ -1106,7 +1106,7 @@ int ast_dsp_call_progress(struct ast_dsp *dsp, struct ast_frame *inf)
 		ast_log(LOG_WARNING, "Can't check call progress of non-voice frames\n");
 		return 0;
 	}
-	if (inf->subclass.codec != AST_FORMAT_SLINEAR) {
+	if (inf->subclass.format.id != AST_FORMAT_SLINEAR) {
 		ast_log(LOG_WARNING, "Can only check call progress in signed-linear frames\n");
 		return 0;
 	}
@@ -1280,7 +1280,7 @@ int ast_dsp_silence(struct ast_dsp *dsp, struct ast_frame *f, int *totalsilence)
 		ast_log(LOG_WARNING, "Can't calculate silence on a non-voice frame\n");
 		return 0;
 	}
-	if (f->subclass.codec != AST_FORMAT_SLINEAR) {
+	if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
 		ast_log(LOG_WARNING, "Can only calculate silence on signed-linear frames :(\n");
 		return 0;
 	}
@@ -1298,7 +1298,7 @@ int ast_dsp_noise(struct ast_dsp *dsp, struct ast_frame *f, int *totalnoise)
                ast_log(LOG_WARNING, "Can't calculate noise on a non-voice frame\n");
                return 0;
        }
-       if (f->subclass.codec != AST_FORMAT_SLINEAR) {
+       if (f->subclass.format.id != AST_FORMAT_SLINEAR) {
                ast_log(LOG_WARNING, "Can only calculate noise on signed-linear frames :(\n");
                return 0;
        }
@@ -1329,7 +1329,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
 	odata = af->data.ptr;
 	len = af->datalen;
 	/* Make sure we have short data */
-	switch (af->subclass.codec) {
+	switch (af->subclass.format.id) {
 	case AST_FORMAT_SLINEAR:
 		shortdata = af->data.ptr;
 		len = af->datalen / 2;
@@ -1350,7 +1350,7 @@ struct ast_frame *ast_dsp_process(struct ast_channel *chan, struct ast_dsp *dsp,
 	default:
 		/*Display warning only once. Otherwise you would get hundreds of warnings every second */
 		if (dsp->display_inband_dtmf_warning)
-			ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(af->subclass.codec));
+			ast_log(LOG_WARNING, "Inband DTMF is not supported on codec %s. Use RFC2833\n", ast_getformatname(&af->subclass.format));
 		dsp->display_inband_dtmf_warning = 0;
 		return af;
 	}
@@ -1479,7 +1479,7 @@ done:
 		memset(shortdata + dsp->mute_data[x].start, 0, sizeof(int16_t) * (dsp->mute_data[x].end - dsp->mute_data[x].start));
 	}
 
-	switch (af->subclass.codec) {
+	switch (af->subclass.format.id) {
 	case AST_FORMAT_SLINEAR:
 		break;
 	case AST_FORMAT_ULAW:
@@ -1491,6 +1491,8 @@ done:
 		for (x = 0; x < len; x++) {
 			odata[x] = AST_LIN2A((unsigned short) shortdata[x]);
 		}
+		/* fall through */
+	default:
 		break;
 	}
 
diff --git a/main/features.c b/main/features.c
index 413f8170a94175fda70f3088f1bc67165e136fa9..f35a2475a8544b0e11e18c073b3974309ae420a1 100644
--- a/main/features.c
+++ b/main/features.c
@@ -743,7 +743,7 @@ static void check_goto_on_transfer(struct ast_channel *chan)
 
 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
 	const char *caller_name, struct ast_channel *requestor,
-	struct ast_channel *transferee, const char *type, format_t format, void *data,
+	struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data,
 	int timeout, int *outstate, const char *language);
 
 /*!
@@ -1315,17 +1315,20 @@ static int fake_fixup(struct ast_channel *clonechan, struct ast_channel *origina
 static struct ast_channel *create_test_channel(const struct ast_channel_tech *fake_tech)
 {
 	struct ast_channel *test_channel1;
+	struct ast_format tmp_fmt;
 	if (!(test_channel1 = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL,
 	NULL, NULL, 0, 0, "TestChannel1"))) {
 		return NULL;
 	}
 
 	/* normally this is done in the channel driver */
-	test_channel1->nativeformats = AST_FORMAT_GSM;
-	test_channel1->writeformat = AST_FORMAT_GSM;
-	test_channel1->rawwriteformat = AST_FORMAT_GSM;
-	test_channel1->readformat = AST_FORMAT_GSM;
-	test_channel1->rawreadformat = AST_FORMAT_GSM;
+	ast_format_cap_add(test_channel1->nativeformats, ast_format_set(&tmp_fmt, AST_FORMAT_GSM, 0));
+
+	ast_format_set(&test_channel1->writeformat, AST_FORMAT_GSM, 0);
+	ast_format_set(&test_channel1->rawwriteformat, AST_FORMAT_GSM, 0);
+	ast_format_set(&test_channel1->readformat, AST_FORMAT_GSM, 0);
+	ast_format_set(&test_channel1->rawreadformat, AST_FORMAT_GSM, 0);
+
 	test_channel1->tech = fake_tech;
 
 	return test_channel1;
@@ -2136,7 +2139,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
 
 	/* Dial party C */
 	newchan = feature_request_and_dial(transferer, transferer_name_orig, transferer,
-		transferee, "Local", ast_best_codec(transferer->nativeformats), xferto,
+		transferee, "Local", transferer->nativeformats, xferto,
 		atxfernoanswertimeout, &outstate, transferer->language);
 	ast_debug(2, "Dial party C result: newchan:%d, outstate:%d\n", !!newchan, outstate);
 
@@ -2243,14 +2246,13 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
 					transferer_tech, transferer_name);
 				newchan = feature_request_and_dial(transferer, transferer_name_orig,
 					transferee, transferee, transferer_tech,
-					ast_best_codec(transferee->nativeformats), transferer_name,
+					transferee->nativeformats, transferer_name,
 					atxfernoanswertimeout, &outstate, transferer->language);
 				ast_debug(2, "Dial party B result: newchan:%d, outstate:%d\n",
 					!!newchan, outstate);
 				if (newchan || ast_check_hangup(transferee)) {
 					break;
 				}
-
 				++tries;
 				if (atxfercallbackretries <= tries) {
 					/* No more callback tries remaining. */
@@ -2272,7 +2274,7 @@ static int builtin_atxfer(struct ast_channel *chan, struct ast_channel *peer, st
 				ast_debug(1, "We're retrying to call %s/%s\n", "Local", xferto);
 				newchan = feature_request_and_dial(transferer, transferer_name_orig,
 					transferer, transferee, "Local",
-					ast_best_codec(transferee->nativeformats), xferto,
+					transferee->nativeformats, xferto,
 					atxfernoanswertimeout, &outstate, transferer->language);
 				ast_debug(2, "Redial party C result: newchan:%d, outstate:%d\n",
 					!!newchan, outstate);
@@ -2980,7 +2982,7 @@ static void set_config_flags(struct ast_channel *chan, struct ast_channel *peer,
  */
 static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
 	const char *caller_name, struct ast_channel *requestor,
-	struct ast_channel *transferee, const char *type, format_t format, void *data,
+	struct ast_channel *transferee, const char *type, struct ast_format_cap *cap, void *data,
 	int timeout, int *outstate, const char *language)
 {
 	int state = 0;
@@ -2996,12 +2998,21 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
 	struct timeval started;
 	int x, len = 0;
 	char *disconnect_code = NULL, *dialed_code = NULL;
+	struct ast_format_cap *tmp_cap;
+	struct ast_format best_audio_fmt;
 	struct ast_frame *f;
 	AST_LIST_HEAD_NOLOCK(, ast_frame) deferred_frames;
 
+	tmp_cap = ast_format_cap_alloc_nolock();
+	if (!tmp_cap) {
+		return NULL;
+	}
+	ast_best_codec(cap, &best_audio_fmt);
+	ast_format_cap_add(tmp_cap, &best_audio_fmt);
+
 	caller_hungup = ast_check_hangup(caller);
 
-	if (!(chan = ast_request(type, format, requestor, data, &cause))) {
+	if (!(chan = ast_request(type, tmp_cap, requestor, data, &cause))) {
 		ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
 		switch (cause) {
 		case AST_CAUSE_BUSY:
@@ -3119,8 +3130,7 @@ static struct ast_channel *feature_request_and_dial(struct ast_channel *caller,
 			}
 		} else if (chan == active_channel) {
 			if (!ast_strlen_zero(chan->call_forward)) {
-				state = 0;
-				chan = ast_call_forward(caller, chan, NULL, format, NULL, &state);
+				chan = ast_call_forward(caller, chan, NULL, tmp_cap, NULL, &state);
 				if (!chan) {
 					break;
 				}
@@ -3252,6 +3262,8 @@ done:
 		chan = NULL;
 	}
 
+	tmp_cap = ast_format_cap_destroy(tmp_cap);
+
 	if (outstate)
 		*outstate = state;
 
diff --git a/main/file.c b/main/file.c
index c2ab096cd004bd98483c10e2f7ff5710dfad831d..57bf1570c0316c405dcd70268ff057e134cc6af8 100644
--- a/main/file.c
+++ b/main/file.c
@@ -59,11 +59,11 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  */
 int ast_language_is_prefix = 1;
 
-static AST_RWLIST_HEAD_STATIC(formats, ast_format);
+static AST_RWLIST_HEAD_STATIC(formats, ast_format_def);
 
-int __ast_format_register(const struct ast_format *f, struct ast_module *mod)
+int __ast_format_def_register(const struct ast_format_def *f, struct ast_module *mod)
 {
-	struct ast_format *tmp;
+	struct ast_format_def *tmp;
 
 	AST_RWLIST_WRLOCK(&formats);
 	AST_RWLIST_TRAVERSE(&formats, tmp, list) {
@@ -98,9 +98,9 @@ int __ast_format_register(const struct ast_format *f, struct ast_module *mod)
 	return 0;
 }
 
-int ast_format_unregister(const char *name)
+int ast_format_def_unregister(const char *name)
 {
-	struct ast_format *tmp;
+	struct ast_format_def *tmp;
 	int res = -1;
 
 	AST_RWLIST_WRLOCK(&formats);
@@ -130,8 +130,8 @@ int ast_stopstream(struct ast_channel *tmp)
 	if (tmp->stream) {
 		ast_closestream(tmp->stream);
 		tmp->stream = NULL;
-		if (tmp->oldwriteformat && ast_set_write_format(tmp, tmp->oldwriteformat))
-			ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(tmp->oldwriteformat));
+		if (tmp->oldwriteformat.id && ast_set_write_format(tmp, &tmp->oldwriteformat))
+			ast_log(LOG_WARNING, "Unable to restore format back to %s\n", ast_getformatname(&tmp->oldwriteformat));
 	}
 	/* Stop the video stream too */
 	if (tmp->vstream != NULL) {
@@ -149,10 +149,10 @@ int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
 	int res = -1;
 	int alt = 0;
 	if (f->frametype == AST_FRAME_VIDEO) {
-		if (fs->fmt->format & AST_FORMAT_AUDIO_MASK) {
+		if (AST_FORMAT_GET_TYPE(fs->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
 			/* This is the audio portion.  Call the video one... */
 			if (!fs->vfs && fs->filename) {
-				const char *type = ast_getformatname(f->subclass.codec & ~0x1);
+				const char *type = ast_getformatname(&f->subclass.format);
 				fs->vfs = ast_writefile(fs->filename, type, NULL, fs->flags, 0, fs->mode);
 				ast_debug(1, "Opened video output file\n");
 			}
@@ -168,7 +168,7 @@ int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
 		ast_log(LOG_WARNING, "Tried to write non-voice frame\n");
 		return -1;
 	}
-	if (((fs->fmt->format | alt) & f->subclass.codec) == f->subclass.codec) {
+	if (ast_format_cmp(&f->subclass.format, &fs->fmt->format) != AST_FORMAT_CMP_NOT_EQUAL) {
 		res =  fs->fmt->write(fs, f);
 		if (res < 0) 
 			ast_log(LOG_WARNING, "Natural write failed\n");
@@ -177,18 +177,18 @@ int ast_writestream(struct ast_filestream *fs, struct ast_frame *f)
 	} else {
 		/* XXX If they try to send us a type of frame that isn't the normal frame, and isn't
 		       the one we've setup a translator for, we do the "wrong thing" XXX */
-		if (fs->trans && f->subclass.codec != fs->lastwriteformat) {
+		if (fs->trans && (ast_format_cmp(&f->subclass.format, &fs->lastwriteformat) != AST_FORMAT_CMP_EQUAL)) {
 			ast_translator_free_path(fs->trans);
 			fs->trans = NULL;
 		}
 		if (!fs->trans) 
-			fs->trans = ast_translator_build_path(fs->fmt->format, f->subclass.codec);
+			fs->trans = ast_translator_build_path(&fs->fmt->format, &f->subclass.format);
 		if (!fs->trans)
 			ast_log(LOG_WARNING, "Unable to translate to format %s, source format %s\n",
-				fs->fmt->name, ast_getformatname(f->subclass.codec));
+				fs->fmt->name, ast_getformatname(&f->subclass.format));
 		else {
 			struct ast_frame *trf;
-			fs->lastwriteformat = f->subclass.codec;
+			ast_format_copy(&fs->lastwriteformat, &f->subclass.format);
 			/* Get the translated frame but don't consume the original in case they're using it on another stream */
 			if ((trf = ast_translate(fs->trans, f, 0))) {
 				struct ast_frame *cur;
@@ -296,7 +296,7 @@ static void filestream_destructor(void *arg)
 
 	/* Stop a running stream if there is one */
 	if (f->owner) {
-		if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
+		if (AST_FORMAT_GET_TYPE(f->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
 			f->owner->stream = NULL;
 			AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
 			ast_settimeout(f->owner, 0, NULL, NULL);
@@ -335,7 +335,7 @@ static void filestream_destructor(void *arg)
 	ast_module_unref(f->fmt->module);
 }
 
-static struct ast_filestream *get_filestream(struct ast_format *fmt, FILE *bfile)
+static struct ast_filestream *get_filestream(struct ast_format_def *fmt, FILE *bfile)
 {
 	struct ast_filestream *s;
 
@@ -361,7 +361,7 @@ enum wrap_fn { WRAP_OPEN, WRAP_REWRITE };
 
 static int fn_wrapper(struct ast_filestream *s, const char *comment, enum wrap_fn mode)
 {
-	struct ast_format *f = s->fmt;
+	struct ast_format_def *f = s->fmt;
 	int ret = -1;
 	int (*openfn)(struct ast_filestream *s);
 
@@ -396,18 +396,20 @@ enum file_action {
 };
 
 /*!
+ * \internal
  * \brief perform various actions on a file. Second argument
- * arg2 depends on the command:
- *	unused for EXISTS and DELETE
+ * \note arg2 depends on the command:
+ *	unused for DELETE
+ *  optional ast_format_cap holding all the formats found for a file, for EXISTS.
  *	destination file name (const char *) for COPY and RENAME
  * 	struct ast_channel * for OPEN
  * if fmt is NULL, OPEN will return the first matching entry,
  * whereas other functions will run on all matching entries.
  */
-static format_t ast_filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
+static int filehelper(const char *filename, const void *arg2, const char *fmt, const enum file_action action)
 {
-	struct ast_format *f;
-	format_t res = (action == ACTION_EXISTS) ? 0 : -1;
+	struct ast_format_def *f;
+	int res = (action == ACTION_EXISTS) ? 0 : -1;
 
 	AST_RWLIST_RDLOCK(&formats);
 	/* Check for a specific format */
@@ -441,9 +443,9 @@ static format_t ast_filehelper(const char *filename, const void *arg2, const cha
 				FILE *bfile;
 				struct ast_filestream *s;
 
-				if ( !(chan->writeformat & f->format) &&
-				     !((f->format & AST_FORMAT_AUDIO_MASK && fmt) ||
-					  (f->format & AST_FORMAT_VIDEO_MASK && fmt))) {
+				if ((ast_format_cmp(&chan->writeformat, &f->format) == AST_FORMAT_CMP_NOT_EQUAL) &&
+				     !(((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_AUDIO) && fmt) ||
+					  ((AST_FORMAT_GET_TYPE(f->format.id) == AST_FORMAT_TYPE_VIDEO) && fmt))) {
 					ast_free(fn);
 					continue;	/* not a supported format */
 				}
@@ -471,7 +473,7 @@ static format_t ast_filehelper(const char *filename, const void *arg2, const cha
 				s->fmt = f;
 				s->trans = NULL;
 				s->filename = NULL;
-				if (s->fmt->format & AST_FORMAT_AUDIO_MASK) {
+				if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
 					if (chan->stream)
 						ast_closestream(chan->stream);
 					chan->stream = s;
@@ -488,7 +490,12 @@ static format_t ast_filehelper(const char *filename, const void *arg2, const cha
 				break;	/* will never get here */
 
 			case ACTION_EXISTS:	/* return the matching format */
-				res |= f->format;
+				/* if arg2 is present, it is a format capabilities structure.
+				 * Add this format to the set of formats this file can be played in */
+				if (arg2) {
+					ast_format_cap_add((struct ast_format_cap *) arg2, &f->format);
+				}
+				res = 1; /* file does exist and format it exists in is returned in arg2 */
 				break;
 
 			case ACTION_DELETE:
@@ -527,11 +534,17 @@ static int is_absolute_path(const char *filename)
 	return filename[0] == '/';
 }
 
-static format_t fileexists_test(const char *filename, const char *fmt, const char *lang,
-			   char *buf, int buflen)
+/*!
+ * \brief test if a file exists for a given format.
+ * \note result_cap is OPTIONAL
+ * \retval 1, true and result_cap represents format capabilities file exists in.
+ * \retval 0, false
+ */
+static int fileexists_test(const char *filename, const char *fmt, const char *lang,
+			   char *buf, int buflen, struct ast_format_cap *result_cap)
 {
 	if (buf == NULL) {
-		return -1;
+		return 0;
 	}
 
 	if (ast_language_is_prefix && !is_absolute_path(filename)) { /* new layout */
@@ -550,25 +563,36 @@ static format_t fileexists_test(const char *filename, const char *fmt, const cha
 		}
 	}
 
-	return ast_filehelper(buf, NULL, fmt, ACTION_EXISTS);
+	return filehelper(buf, result_cap, fmt, ACTION_EXISTS);
 }
 
 /*!
  * \brief helper routine to locate a file with a given format
  * and language preference.
- * Try preflang, preflang with stripped '_' suffices, or NULL.
+ * 
+ * \note Try preflang, preflang with stripped '_' suffices, or NULL.
  *
- * The last parameter(s) point to a buffer of sufficient size,
+ * \note The last parameter(s) point to a buffer of sufficient size,
  * which on success is filled with the matching filename.
+ *
+ * \param filename, name of the file.
+ * \param fmt, format to look for the file in. OPTIONAL
+ * \param preflang, the perfered language
+ * \param buf, returns the matching filename
+ * \param buflen, size of the buf
+ * \param result_cap, OPTIONAL format capabilities result structure
+ *        returns what formats the file was found in.
+ *
+ * \retval 1, true. file exists and result format is set
+ * \retval 0, false. file does not exist.
  */
-static format_t fileexists_core(const char *filename, const char *fmt, const char *preflang,
-			   char *buf, int buflen)
+static int fileexists_core(const char *filename, const char *fmt, const char *preflang,
+			   char *buf, int buflen, struct ast_format_cap *result_cap)
 {
-	format_t res = -1;
 	char *lang;
 
 	if (buf == NULL) {
-		return -1;
+		return 0;
 	}
 
 	/* We try languages in the following order:
@@ -584,8 +608,8 @@ static format_t fileexists_core(const char *filename, const char *fmt, const cha
 	while (!ast_strlen_zero(lang)) {
 		char *end;
 
-		if ((res = fileexists_test(filename, fmt, lang, buf, buflen)) > 0) {
-			return res;
+		if (fileexists_test(filename, fmt, lang, buf, buflen, result_cap)) {
+			return 1;
 		}
 
 		if ((end = strrchr(lang, '_')) != NULL) {
@@ -597,14 +621,14 @@ static format_t fileexists_core(const char *filename, const char *fmt, const cha
 	}
 
 	/* Try without any language */
-	if ((res = fileexists_test(filename, fmt, NULL, buf, buflen)) > 0) {
-		return res;
+	if (fileexists_test(filename, fmt, NULL, buf, buflen, result_cap)) {
+		return 1;
 	}
 
 	/* Finally try the default language unless it was already tried before */
 	if ((ast_strlen_zero(preflang) || strcmp(preflang, DEFAULT_LANGUAGE)) && (ast_strlen_zero(lang) || strcmp(lang, DEFAULT_LANGUAGE))) {
-		if ((res = fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen)) > 0) {
-			return res;
+		if ((fileexists_test(filename, fmt, DEFAULT_LANGUAGE, buf, buflen, result_cap)) > 0) {
+			return 1;
 		}
 	}
 
@@ -623,7 +647,8 @@ struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char
 	 * language and format, set up a suitable translator,
 	 * and open the stream.
 	 */
-	format_t fmts, res;
+	struct ast_format_cap *file_fmt_cap;
+	int res;
 	int buflen;
 	char *buf;
 
@@ -639,20 +664,29 @@ struct ast_filestream *ast_openstream_full(struct ast_channel *chan, const char
 	buf = alloca(buflen);
 	if (buf == NULL)
 		return NULL;
-	fmts = fileexists_core(filename, NULL, preflang, buf, buflen);
-	if (fmts > 0)
-		fmts &= AST_FORMAT_AUDIO_MASK;
-	if (fmts < 1) {
+
+	if (!(file_fmt_cap = ast_format_cap_alloc_nolock())) {
+		return NULL;
+	}
+	if (!fileexists_core(filename, NULL, preflang, buf, buflen, file_fmt_cap) ||
+		!ast_format_cap_has_type(file_fmt_cap, AST_FORMAT_TYPE_AUDIO)) {
+
 		ast_log(LOG_WARNING, "File %s does not exist in any format\n", filename);
+		file_fmt_cap = ast_format_cap_destroy(file_fmt_cap);
 		return NULL;
 	}
-	chan->oldwriteformat = chan->writeformat;
-	/* Set the channel to a format we can work with */
-	res = ast_set_write_format(chan, fmts);
+
+	/* Set the channel to a format we can work with and save off the previous format. */
+	ast_format_copy(&chan->oldwriteformat, &chan->writeformat);
+	/* Set the channel to the best format that exists for the file. */
+	res = ast_set_write_format_from_cap(chan, file_fmt_cap);
+	/* don't need this anymore now that the channel's write format is set. */
+	file_fmt_cap = ast_format_cap_destroy(file_fmt_cap);
+
 	if (res == -1) {	/* No format available that works with this channel */
 		return NULL;
 	}
-	res = ast_filehelper(buf, chan, NULL, ACTION_OPEN);
+	res = filehelper(buf, chan, NULL, ACTION_OPEN);
 	if (res >= 0)
 		return chan->stream;
 	return NULL;
@@ -663,9 +697,12 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
 	/* As above, but for video. But here we don't have translators
 	 * so we must enforce a format.
 	 */
-	format_t format;
+	struct ast_format tmp_fmt;
+	struct ast_format_cap *tmp_cap;
 	char *buf;
 	int buflen;
+	const char *fmt;
+	int fd;
 
 	if (preflang == NULL)
 		preflang = "";
@@ -674,20 +711,39 @@ struct ast_filestream *ast_openvstream(struct ast_channel *chan, const char *fil
 	if (buf == NULL)
 		return NULL;
 
-	for (format = AST_FORMAT_AUDIO_MASK + 1; format <= AST_FORMAT_VIDEO_MASK; format = format << 1) {
-		int fd;
-		const char *fmt;
+	/* is the channel capable of video without translation ?*/
+	if (!ast_format_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_VIDEO)) {
+		return NULL;
+	}
+	if (!(tmp_cap = ast_format_cap_alloc_nolock())) {
+		return NULL;
+	}
+	/* Video is supported, so see what video formats exist for this file */
+	if (!fileexists_core(filename, NULL, preflang, buf, buflen, tmp_cap)) {
+		tmp_cap = ast_format_cap_destroy(tmp_cap);
+		return NULL;
+	}
 
-		if (!(chan->nativeformats & format))
+	/* iterate over file formats and pick the first one compatible with the channel's native formats */
+	ast_format_cap_iter_start(tmp_cap);
+	while (!ast_format_cap_iter_next(tmp_cap, &tmp_fmt)) {
+		fmt = ast_getformatname(&tmp_fmt);
+		if ((AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) ||
+			!ast_format_cap_iscompatible(chan->nativeformats, &tmp_fmt)) {
 			continue;
-		fmt = ast_getformatname(format);
-		if ( fileexists_core(filename, fmt, preflang, buf, buflen) < 1)	/* no valid format */
-			continue;
-	 	fd = ast_filehelper(buf, chan, fmt, ACTION_OPEN);
-		if (fd >= 0)
+		}
+
+		fd = filehelper(buf, chan, fmt, ACTION_OPEN);
+		if (fd >= 0) {
+			ast_format_cap_iter_end(tmp_cap);
+			tmp_cap = ast_format_cap_destroy(tmp_cap);
 			return chan->vstream;
+		}
 		ast_log(LOG_WARNING, "File %s has video but couldn't be opened\n", filename);
 	}
+	ast_format_cap_iter_end(tmp_cap);
+	tmp_cap = ast_format_cap_destroy(tmp_cap);
+
 	return NULL;
 }
 
@@ -759,7 +815,7 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
 
 	if (whennext != s->lasttimeout) {
 		if (s->owner->timingfd > -1) {
-			float samp_rate = (float) ast_format_rate(s->fmt->format);
+			float samp_rate = (float) ast_format_rate(&s->fmt->format);
 			unsigned int rate;
 
 			rate = (unsigned int) roundf(samp_rate / ((float) whennext));
@@ -767,7 +823,7 @@ static enum fsread_res ast_readaudio_callback(struct ast_filestream *s)
 			ast_settimeout(s->owner, rate, ast_fsread_audio, s);
 		} else {
 			s->owner->streamid = ast_sched_add(s->owner->sched, 
-				whennext / (ast_format_rate(s->fmt->format) / 1000), ast_fsread_audio, s);
+				whennext / (ast_format_rate(&s->fmt->format) / 1000), ast_fsread_audio, s);
 		}
 		s->lasttimeout = whennext;
 		return FSREAD_SUCCESS_NOSCHED;
@@ -818,7 +874,7 @@ static enum fsread_res ast_readvideo_callback(struct ast_filestream *s)
 
 	if (whennext != s->lasttimeout) {
 		s->owner->vstreamid = ast_sched_add(s->owner->sched, 
-			whennext / (ast_format_rate(s->fmt->format) / 1000), 
+			whennext / (ast_format_rate(&s->fmt->format) / 1000), 
 			ast_fsread_video, s);
 		s->lasttimeout = whennext;
 		return FSREAD_SUCCESS_NOSCHED;
@@ -850,7 +906,7 @@ int ast_playstream(struct ast_filestream *s)
 {
 	enum fsread_res res;
 
-	if (s->fmt->format & AST_FORMAT_AUDIO_MASK)
+	if (AST_FORMAT_GET_TYPE(s->fmt->format.id) == AST_FORMAT_TYPE_AUDIO)
 		res = ast_readaudio_callback(s);
 	else
 		res = ast_readvideo_callback(s);
@@ -892,7 +948,7 @@ int ast_closestream(struct ast_filestream *f)
 
 	/* Stop a running stream if there is one */
 	if (f->owner) {
-		if (f->fmt->format < AST_FORMAT_AUDIO_MASK) {
+		if (AST_FORMAT_GET_TYPE(f->fmt->format.id) == AST_FORMAT_TYPE_AUDIO) {
 			f->owner->stream = NULL;
 			AST_SCHED_DEL(f->owner->sched, f->owner->streamid);
 			ast_settimeout(f->owner, 0, NULL, NULL);
@@ -921,22 +977,22 @@ int ast_fileexists(const char *filename, const char *fmt, const char *preflang)
 	buf = alloca(buflen);
 	if (buf == NULL)
 		return 0;
-	return fileexists_core(filename, fmt, preflang, buf, buflen);
+	return fileexists_core(filename, fmt, preflang, buf, buflen, NULL) ? 1 : 0;
 }
 
 int ast_filedelete(const char *filename, const char *fmt)
 {
-	return ast_filehelper(filename, NULL, fmt, ACTION_DELETE);
+	return filehelper(filename, NULL, fmt, ACTION_DELETE);
 }
 
 int ast_filerename(const char *filename, const char *filename2, const char *fmt)
 {
-	return ast_filehelper(filename, filename2, fmt, ACTION_RENAME);
+	return filehelper(filename, filename2, fmt, ACTION_RENAME);
 }
 
 int ast_filecopy(const char *filename, const char *filename2, const char *fmt)
 {
-	return ast_filehelper(filename, filename2, fmt, ACTION_COPY);
+	return filehelper(filename, filename2, fmt, ACTION_COPY);
 }
 
 int ast_streamfile(struct ast_channel *chan, const char *filename, const char *preflang)
@@ -966,7 +1022,7 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
 
 	vfs = ast_openvstream(chan, filename, preflang);
 	if (vfs) {
-		ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(vfs->fmt->format));
+		ast_debug(1, "Ooh, found a video stream, too, format %s\n", ast_getformatname(&vfs->fmt->format));
 	}
 
 	if (ast_test_flag(chan, AST_FLAG_MASQ_NOSTREAM))
@@ -978,7 +1034,7 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
 	res = ast_playstream(fs);
 	if (!res && vfs)
 		res = ast_playstream(vfs);
-	ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(chan->writeformat), preflang ? preflang : "default");
+	ast_verb(3, "<%s> Playing '%s.%s' (language '%s')\n", chan->name, filename, ast_getformatname(&chan->writeformat), preflang ? preflang : "default");
 
 	return res;
 }
@@ -986,7 +1042,7 @@ int ast_streamfile(struct ast_channel *chan, const char *filename, const char *p
 struct ast_filestream *ast_readfile(const char *filename, const char *type, const char *comment, int flags, int check, mode_t mode)
 {
 	FILE *bfile;
-	struct ast_format *f;
+	struct ast_format_def *f;
 	struct ast_filestream *fs = NULL;
 	char *fn;
 	int format_found = 0;	
@@ -1036,7 +1092,7 @@ struct ast_filestream *ast_writefile(const char *filename, const char *type, con
 	int fd, myflags = 0;
 	/* compiler claims this variable can be used before initialization... */
 	FILE *bfile = NULL;
-	struct ast_format *f;
+	struct ast_format_def *f;
 	struct ast_filestream *fs = NULL;
 	char *buf = NULL;
 	size_t size = 0;
@@ -1359,8 +1415,8 @@ int ast_stream_and_wait(struct ast_channel *chan, const char *file, const char *
 
 char *ast_format_str_reduce(char *fmts)
 {
-	struct ast_format *f;
-	struct ast_format *fmts_ptr[AST_MAX_FORMATS];
+	struct ast_format_def *f;
+	struct ast_format_def *fmts_ptr[AST_MAX_FORMATS];
 	char *fmts_str[AST_MAX_FORMATS];
 	char *stringp, *type;
 	char *orig = fmts;
@@ -1437,7 +1493,7 @@ static char *handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd,
 {
 #define FORMAT "%-10s %-10s %-20s\n"
 #define FORMAT2 "%-10s %-10s %-20s\n"
-	struct ast_format *f;
+	struct ast_format_def *f;
 	int count_fmt = 0;
 
 	switch (cmd) {
@@ -1459,7 +1515,7 @@ static char *handle_cli_core_show_file_formats(struct ast_cli_entry *e, int cmd,
 
 	AST_RWLIST_RDLOCK(&formats);
 	AST_RWLIST_TRAVERSE(&formats, f, list) {
-		ast_cli(a->fd, FORMAT2, ast_getformatname(f->format), f->name, f->exts);
+		ast_cli(a->fd, FORMAT2, ast_getformatname(&f->format), f->name, f->exts);
 		count_fmt++;
 	}
 	AST_RWLIST_UNLOCK(&formats);
diff --git a/main/format.c b/main/format.c
new file mode 100644
index 0000000000000000000000000000000000000000..d77d244a644d4239f10bb304c2470898ce734122
--- /dev/null
+++ b/main/format.c
@@ -0,0 +1,558 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * David Vossel <dvossel@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format API
+ *
+ * \author David Vossel <dvossel@digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
+
+#include "asterisk/_private.h"
+#include "asterisk/version.h"
+#include "asterisk/format.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/lock.h"
+
+/*! This is the container for all the format attribute interfaces.
+ *  An ao2 container was chosen for fast lookup. */
+static struct ao2_container *interfaces;
+
+/*! This is the lock used to protect the interfaces container.  Yes, ao2_containers
+ * do have their own locking, but we need the capability of performing read/write
+ * locks on this specific container. */
+static ast_rwlock_t ilock;
+
+/*! a wrapper is used put interfaces into the ao2 container. */
+struct interface_ao2_wrapper {
+	enum ast_format_id id;
+	const struct ast_format_attr_interface *interface;
+	/*! a read write lock must be used to protect the wrapper instead
+	 * of the ao2 lock. */
+	ast_rwlock_t wraplock;
+};
+
+static int interface_cmp_cb(void *obj, void *arg, int flags)
+{
+	struct interface_ao2_wrapper *wrapper1 = obj;
+	struct interface_ao2_wrapper *wrapper2 = arg;
+
+	return (wrapper2->id == wrapper1->id) ? CMP_MATCH | CMP_STOP : 0;
+}
+
+static int interface_hash_cb(const void *obj, const int flags)
+{
+	const struct interface_ao2_wrapper *wrapper = obj;
+	return wrapper->id;
+}
+
+static void interface_destroy_cb(void *obj)
+{
+	struct interface_ao2_wrapper *wrapper = obj;
+	ast_rwlock_destroy(&wrapper->wraplock);
+}
+
+void ast_format_copy(struct ast_format *dst, const struct ast_format *src)
+{
+	memcpy(dst, src, sizeof(struct ast_format));
+}
+
+void ast_format_set_video_mark(struct ast_format *format)
+{
+	format->fattr.rtp_marker_bit = 1;
+}
+
+int ast_format_get_video_mark(const struct ast_format *format)
+{
+	return format->fattr.rtp_marker_bit;
+}
+
+static struct interface_ao2_wrapper *find_interface(const struct ast_format *format)
+{
+	struct interface_ao2_wrapper *wrapper;
+	struct interface_ao2_wrapper tmp_wrapper = {
+		.id = format->id,
+	};
+
+	ast_rwlock_rdlock(&ilock);
+	if (!(wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_NOLOCK)))) {
+		ast_rwlock_unlock(&ilock);
+		return NULL;
+	}
+	ast_rwlock_unlock(&ilock);
+
+	return wrapper;
+}
+
+/*! \internal
+ * \brief set format attributes using an interface
+ */
+static int format_set_helper(struct ast_format *format, va_list ap)
+{
+	struct interface_ao2_wrapper *wrapper;
+
+	if (!(wrapper = find_interface(format))) {
+		ast_log(LOG_WARNING, "Could not find format interface to set.\n");
+		return -1;
+	}
+
+	ast_rwlock_rdlock(&wrapper->wraplock);
+	if (!wrapper->interface || !wrapper->interface->format_attr_set) {
+		ast_rwlock_unlock(&wrapper->wraplock);
+		ao2_ref(wrapper, -1);
+		return -1;
+	}
+
+	wrapper->interface->format_attr_set(&format->fattr, ap);
+
+	ast_rwlock_unlock(&wrapper->wraplock);
+	ao2_ref(wrapper, -1);
+
+	return 0;
+}
+
+struct ast_format *ast_format_append(struct ast_format *format, ... )
+{
+	va_list ap;
+	va_start(ap, format);
+	format_set_helper(format, ap);
+	va_end(ap);
+
+	return format;
+}
+
+struct ast_format *ast_format_set(struct ast_format *format, enum ast_format_id id, int set_attributes, ... )
+{
+	/* initialize the structure before setting it. */
+	ast_format_clear(format);
+
+	format->id = id;
+
+	if (set_attributes) {
+		va_list ap;
+		va_start(ap, set_attributes);
+		format_set_helper(format, ap);
+		va_end(ap);
+	}
+
+	return format;
+}
+
+void ast_format_clear(struct ast_format *format)
+{
+	format->id = 0;
+	memset(&format->fattr, 0, sizeof(format->fattr));
+}
+
+/*! \internal
+ * \brief determine if a list of attribute key value pairs are set on a format
+ */
+static int format_isset_helper(struct ast_format *format, va_list ap)
+{
+	int res;
+	struct interface_ao2_wrapper *wrapper;
+	struct ast_format tmp = {
+		.id = format->id,
+		.fattr = { { 0, }, },
+	};
+
+	if (!(wrapper = find_interface(format))) {
+		return -1;
+	}
+
+	ast_rwlock_rdlock(&wrapper->wraplock);
+	if (!wrapper->interface ||
+		!wrapper->interface->format_attr_set ||
+		!wrapper->interface->format_attr_cmp) {
+
+		ast_rwlock_unlock(&wrapper->wraplock);
+		ao2_ref(wrapper, -1);
+		return -1;
+	}
+
+	wrapper->interface->format_attr_set(&tmp.fattr, ap);
+
+	/* use our tmp structure to tell if the attributes are set or not */
+	res = wrapper->interface->format_attr_cmp(&tmp.fattr, &format->fattr);
+
+	ast_rwlock_unlock(&wrapper->wraplock);
+	ao2_ref(wrapper, -1);
+
+	return (res == AST_FORMAT_CMP_NOT_EQUAL) ? -1 : 0;
+}
+
+int ast_format_isset(struct ast_format *format, ... )
+{
+	va_list ap;
+	int res;
+
+	va_start(ap, format);
+	res = format_isset_helper(format, ap);
+	va_end(ap);
+	return res;
+}
+
+
+/*! \internal
+ * \brief cmp format attributes using an interface
+ */
+static enum ast_format_cmp_res format_cmp_helper(const struct ast_format *format1, const struct ast_format *format2)
+{
+	enum ast_format_cmp_res res = AST_FORMAT_CMP_EQUAL;
+	struct interface_ao2_wrapper *wrapper;
+
+	if (!(wrapper = find_interface(format1))) {
+		return res;
+	}
+
+	ast_rwlock_rdlock(&wrapper->wraplock);
+	if (!wrapper->interface || !wrapper->interface->format_attr_cmp) {
+		ast_rwlock_unlock(&wrapper->wraplock);
+		ao2_ref(wrapper, -1);
+		return res;
+	}
+
+	res = wrapper->interface->format_attr_cmp(&format1->fattr, &format2->fattr);
+
+	ast_rwlock_unlock(&wrapper->wraplock);
+	ao2_ref(wrapper, -1);
+
+	return res;
+}
+
+enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
+{
+	if (format1->id != format2->id) {
+		return AST_FORMAT_CMP_NOT_EQUAL;
+	}
+
+	return format_cmp_helper(format1, format2);
+}
+
+/*! \internal
+ * \brief get joint format attributes using an interface
+ */
+static int format_joint_helper(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result)
+{
+	int res = 0;
+	struct interface_ao2_wrapper *wrapper;
+
+	if (!(wrapper = find_interface(format1))) {
+		/* if no interface is present, we assume formats are joint by id alone */
+		return res;
+	}
+
+	ast_rwlock_rdlock(&wrapper->wraplock);
+	if (wrapper->interface && wrapper->interface->format_attr_get_joint) {
+		res = wrapper->interface->format_attr_get_joint(&format1->fattr, &format2->fattr, &result->fattr);
+	}
+	ast_rwlock_unlock(&wrapper->wraplock);
+
+	ao2_ref(wrapper, -1);
+
+	return res;
+}
+
+int ast_format_joint(const struct ast_format *format1, const struct ast_format *format2, struct ast_format *result)
+{
+	if (format1->id != format2->id) {
+		return -1;
+	}
+	result->id = format1->id;
+	return format_joint_helper(format1, format2, result);
+}
+
+
+uint64_t ast_format_id_to_old_bitfield(enum ast_format_id id)
+{
+	switch (id) {
+	/*! G.723.1 compression */
+	case AST_FORMAT_G723_1:
+		return (1ULL << 0);
+	/*! GSM compression */
+	case AST_FORMAT_GSM:
+		return (1ULL << 1);
+	/*! Raw mu-law data (G.711) */
+	case AST_FORMAT_ULAW:
+		return (1ULL << 2);
+	/*! Raw A-law data (G.711) */
+	case AST_FORMAT_ALAW:
+		return (1ULL << 3);
+	/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
+	case AST_FORMAT_G726_AAL2:
+		return (1ULL << 4);
+	/*! ADPCM (IMA) */
+	case AST_FORMAT_ADPCM:
+		return (1ULL << 5);
+	/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
+	case AST_FORMAT_SLINEAR:
+		return (1ULL << 6);
+	/*! LPC10, 180 samples/frame */
+	case AST_FORMAT_LPC10:
+		return (1ULL << 7);
+	/*! G.729A audio */
+	case AST_FORMAT_G729A:
+		return (1ULL << 8);
+	/*! SpeeX Free Compression */
+	case AST_FORMAT_SPEEX:
+		return (1ULL << 9);
+	/*! iLBC Free Compression */
+	case AST_FORMAT_ILBC:
+		return (1ULL << 10);
+	/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
+	case AST_FORMAT_G726:
+		return (1ULL << 11);
+	/*! G.722 */
+	case AST_FORMAT_G722:
+		return (1ULL << 12);
+	/*! G.722.1 (also known as Siren7, 32kbps assumed) */
+	case AST_FORMAT_SIREN7:
+		return (1ULL << 13);
+	/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
+	case AST_FORMAT_SIREN14:
+		return (1ULL << 14);
+	/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
+	case AST_FORMAT_SLINEAR16:
+		return (1ULL << 15);
+	/*! G.719 (64 kbps assumed) */
+	case AST_FORMAT_G719:
+		return (1ULL << 32);
+	/*! SpeeX Wideband (16kHz) Free Compression */
+	case AST_FORMAT_SPEEX16:
+		return (1ULL << 33);
+	/*! Raw mu-law data (G.711) */
+	case AST_FORMAT_TESTLAW:
+		return (1ULL << 47);
+
+	/*! H.261 Video */
+	case AST_FORMAT_H261:
+		return (1ULL << 18);
+	/*! H.263 Video */
+	case AST_FORMAT_H263:
+		return (1ULL << 19);
+	/*! H.263+ Video */
+	case AST_FORMAT_H263_PLUS:
+		return (1ULL << 20);
+	/*! H.264 Video */
+	case AST_FORMAT_H264:
+		return (1ULL << 21);
+	/*! MPEG4 Video */
+	case AST_FORMAT_MP4_VIDEO:
+		return (1ULL << 22);
+
+	/*! JPEG Images */
+	case AST_FORMAT_JPEG:
+		return (1ULL << 16);
+	/*! PNG Images */
+	case AST_FORMAT_PNG:
+		return (1ULL << 17);
+
+	/*! T.140 RED Text format RFC 4103 */
+	case AST_FORMAT_T140RED:
+		return (1ULL << 26);
+	/*! T.140 Text format - ITU T.140, RFC 4103 */
+	case AST_FORMAT_T140:
+		return (1ULL << 27);
+	}
+
+	return 0;
+
+}
+uint64_t ast_format_to_old_bitfield(const struct ast_format *format)
+{
+	return ast_format_id_to_old_bitfield(format->id);
+}
+
+struct ast_format *ast_format_from_old_bitfield(struct ast_format *dst, uint64_t src)
+{
+	switch (src) {
+	/*! G.723.1 compression */
+	case (1ULL << 0):
+		return ast_format_set(dst, AST_FORMAT_G723_1, 0);
+	/*! GSM compression */
+	case (1ULL << 1):
+		return ast_format_set(dst, AST_FORMAT_GSM, 0);
+	/*! Raw mu-law data (G.711) */
+	case (1ULL << 2):
+		return ast_format_set(dst, AST_FORMAT_ULAW, 0);
+	/*! Raw A-law data (G.711) */
+	case (1ULL << 3):
+		return ast_format_set(dst, AST_FORMAT_ALAW, 0);
+	/*! ADPCM (G.726, 32kbps, AAL2 codeword packing) */
+	case (1ULL << 4):
+		return ast_format_set(dst, AST_FORMAT_G726_AAL2, 0);
+	/*! ADPCM (IMA) */
+	case (1ULL << 5):
+		return ast_format_set(dst, AST_FORMAT_ADPCM, 0);
+	/*! Raw 16-bit Signed Linear (8000 Hz) PCM */
+	case (1ULL << 6):
+		return ast_format_set(dst, AST_FORMAT_SLINEAR, 0);
+	/*! LPC10, 180 samples/frame */
+	case (1ULL << 7):
+		return ast_format_set(dst, AST_FORMAT_LPC10, 0);
+	/*! G.729A audio */
+	case (1ULL << 8):
+		return ast_format_set(dst, AST_FORMAT_G729A, 0);
+	/*! SpeeX Free Compression */
+	case (1ULL << 9):
+		return ast_format_set(dst, AST_FORMAT_SPEEX, 0);
+	/*! iLBC Free Compression */
+	case (1ULL << 10):
+		return ast_format_set(dst, AST_FORMAT_ILBC, 0);
+	/*! ADPCM (G.726, 32kbps, RFC3551 codeword packing) */
+	case (1ULL << 11):
+		return ast_format_set(dst, AST_FORMAT_G726, 0);
+	/*! G.722 */
+	case (1ULL << 12):
+		return ast_format_set(dst, AST_FORMAT_G722, 0);
+	/*! G.722.1 (also known as Siren7, 32kbps assumed) */
+	case (1ULL << 13):
+		return ast_format_set(dst, AST_FORMAT_SIREN7, 0);
+	/*! G.722.1 Annex C (also known as Siren14, 48kbps assumed) */
+	case (1ULL << 14):
+		return ast_format_set(dst, AST_FORMAT_SIREN14, 0);
+	/*! Raw 16-bit Signed Linear (16000 Hz) PCM */
+	case (1ULL << 15):
+		return ast_format_set(dst, AST_FORMAT_SLINEAR16, 0);
+	/*! G.719 (64 kbps assumed) */
+	case (1ULL << 32):
+		return ast_format_set(dst, AST_FORMAT_G719, 0);
+	/*! SpeeX Wideband (16kHz) Free Compression */
+	case (1ULL << 33):
+		return ast_format_set(dst, AST_FORMAT_SPEEX16, 0);
+	/*! Raw mu-law data (G.711) */
+	case (1ULL << 47):
+		return ast_format_set(dst, AST_FORMAT_TESTLAW, 0);
+
+	/*! H.261 Video */
+	case (1ULL << 18):
+		return ast_format_set(dst, AST_FORMAT_H261, 0);
+	/*! H.263 Video */
+	case (1ULL << 19):
+		return ast_format_set(dst, AST_FORMAT_H263, 0);
+	/*! H.263+ Video */
+	case (1ULL << 20):
+		return ast_format_set(dst, AST_FORMAT_H263_PLUS, 0);
+	/*! H.264 Video */
+	case (1ULL << 21):
+		return ast_format_set(dst, AST_FORMAT_H264, 0);
+	/*! MPEG4 Video */
+	case (1ULL << 22):
+		return ast_format_set(dst, AST_FORMAT_MP4_VIDEO, 0);
+
+	/*! JPEG Images */
+	case (1ULL << 16):
+		return ast_format_set(dst, AST_FORMAT_JPEG, 0);
+	/*! PNG Images */
+	case (1ULL << 17):
+		return ast_format_set(dst, AST_FORMAT_PNG, 0);
+
+	/*! T.140 RED Text format RFC 4103 */
+	case (1ULL << 26):
+		return ast_format_set(dst, AST_FORMAT_T140RED, 0);
+	/*! T.140 Text format - ITU T.140, RFC 4103 */
+	case (1ULL << 27):
+		return ast_format_set(dst, AST_FORMAT_T140, 0);
+	}
+	ast_format_clear(dst);
+	return NULL;
+}
+
+enum ast_format_id ast_format_id_from_old_bitfield(uint64_t src)
+{
+	struct ast_format dst;
+	if (ast_format_from_old_bitfield(&dst, src)) {
+		return dst.id;
+	}
+	return 0;
+}
+
+int ast_format_attr_init()
+{
+	if (ast_rwlock_init(&ilock)) {
+		return -1;
+	}
+	if (!(interfaces = ao2_container_alloc(283, interface_hash_cb, interface_cmp_cb))) {
+		ast_rwlock_destroy(&ilock);
+		return -1;
+	}
+	return 0;
+}
+
+int ast_format_attr_reg_interface(const struct ast_format_attr_interface *interface)
+{
+	struct interface_ao2_wrapper *wrapper;
+	struct interface_ao2_wrapper tmp_wrapper = {
+		.id = interface->id,
+	};
+
+	/* check for duplicates first*/
+	ast_rwlock_wrlock(&ilock);
+	if ((wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_NOLOCK)))) {
+		ast_rwlock_unlock(&ilock);
+		ast_log(LOG_WARNING, "Can not register attribute interface for format id %d, interface already exists.\n", interface->id);
+		ao2_ref(wrapper, -1);
+		return -1;
+	}
+	ast_rwlock_unlock(&ilock);
+
+	if (!(wrapper = ao2_alloc(sizeof(*wrapper), interface_destroy_cb))) {
+		return -1;
+	}
+
+	wrapper->interface = interface;
+	wrapper->id = interface->id;
+	ast_rwlock_init(&wrapper->wraplock);
+
+	/* use the write lock whenever the interface container is modified */
+	ast_rwlock_wrlock(&ilock);
+	ao2_link(interfaces, wrapper);
+	ast_rwlock_unlock(&ilock);
+
+	ao2_ref(wrapper, -1);
+
+	return 0;
+}
+
+int ast_format_attr_unreg_interface(const struct ast_format_attr_interface *interface)
+{
+	struct interface_ao2_wrapper *wrapper;
+	struct interface_ao2_wrapper tmp_wrapper = {
+		.id = interface->id,
+	};
+
+	/* use the write lock whenever the interface container is modified */
+	ast_rwlock_wrlock(&ilock);
+	if (!(wrapper = ao2_find(interfaces, &tmp_wrapper, (OBJ_POINTER | OBJ_UNLINK | OBJ_NOLOCK)))) {
+		ast_rwlock_unlock(&ilock);
+		return -1;
+	}
+	ast_rwlock_unlock(&ilock);
+
+	ast_rwlock_wrlock(&wrapper->wraplock);
+	wrapper->interface = NULL;
+	ast_rwlock_unlock(&wrapper->wraplock);
+
+	ao2_ref(wrapper, -1);
+
+	return 0;
+}
diff --git a/main/format_cap.c b/main/format_cap.c
new file mode 100644
index 0000000000000000000000000000000000000000..1d566050f7fd22372e97be9d0ff7f31c3bb12b84
--- /dev/null
+++ b/main/format_cap.c
@@ -0,0 +1,545 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * David Vossel <dvossel@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format Capability API
+ *
+ * \author David Vossel <dvossel@digium.com>
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
+
+#include "asterisk/_private.h"
+#include "asterisk/version.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
+#include "asterisk/frame.h"
+#include "asterisk/astobj2.h"
+#include "asterisk/utils.h"
+
+
+struct ast_format_cap {
+	/* The capabilities structure is just an ao2 container of ast_formats */
+	struct ao2_container *formats;
+	struct ao2_iterator it;
+	int nolock;
+};
+
+/*! format exists within capabilities structure if it is identical to
+ * another format, or if the format is a proper subset of another format. */
+static int cmp_cb(void *obj, void *arg, int flags)
+{
+	struct ast_format *format1 = arg;
+	struct ast_format *format2 = obj;
+	enum ast_format_cmp_res res = ast_format_cmp(format1, format2);
+
+	return ((res == AST_FORMAT_CMP_EQUAL) ||
+			(res == AST_FORMAT_CMP_SUBSET)) ?
+				CMP_MATCH | CMP_STOP :
+				0;
+}
+
+static int hash_cb(const void *obj, const int flags)
+{
+	const struct ast_format *format = obj;
+	return format->id;
+}
+
+static struct ast_format_cap *cap_alloc_helper(int nolock)
+{
+	struct ast_format_cap *cap = ast_calloc(1, sizeof(*cap));
+
+	if (!cap) {
+		return NULL;
+	}
+	cap->nolock = nolock ? OBJ_NOLOCK : 0;
+	if (!(cap->formats = ao2_container_alloc(283, hash_cb, cmp_cb))) {
+		ast_free(cap);
+		return NULL;
+	}
+
+	return cap;
+}
+
+struct ast_format_cap *ast_format_cap_alloc_nolock(void)
+{
+	return cap_alloc_helper(1);
+}
+
+struct ast_format_cap *ast_format_cap_alloc(void)
+{
+	return cap_alloc_helper(0);
+}
+
+void *ast_format_cap_destroy(struct ast_format_cap *cap)
+{
+	if (!cap) {
+		return NULL;
+	}
+	ao2_ref(cap->formats, -1);
+	ast_free(cap);
+	return NULL;
+}
+
+void ast_format_cap_add(struct ast_format_cap *cap, struct ast_format *format)
+{
+	struct ast_format *fnew;
+
+	if (!format || !format->id) {
+		return;
+	}
+	if (!(fnew = ao2_alloc(sizeof(struct ast_format), NULL))) {
+		return;
+	}
+	ast_format_copy(fnew, format);
+	if (cap->nolock) {
+		ao2_link_nolock(cap->formats, fnew);
+	} else {
+		ao2_link(cap->formats, fnew);
+	}
+	ao2_ref(fnew, -1);
+}
+
+void ast_format_cap_add_all_by_type(struct ast_format_cap *cap, enum ast_format_type type)
+{
+	int x;
+	size_t f_len = 0;
+	struct ast_format tmp_fmt;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	for (x = 0; x < f_len; x++) {
+		if (AST_FORMAT_GET_TYPE(f_list[x].id) == type) {
+			ast_format_cap_add(cap, ast_format_set(&tmp_fmt, f_list[x].id, 0));
+		}
+	}
+}
+
+void ast_format_cap_add_all(struct ast_format_cap *cap)
+{
+	int x;
+	size_t f_len = 0;
+	struct ast_format tmp_fmt;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	for (x = 0; x < f_len; x++) {
+		ast_format_cap_add(cap, ast_format_set(&tmp_fmt, f_list[x].id, 0));
+	}
+}
+
+static int append_cb(void *obj, void *arg, int flag)
+{
+	struct ast_format_cap *result = (struct ast_format_cap *) arg;
+	struct ast_format *format = (struct ast_format *) obj;
+
+	if (!ast_format_cap_iscompatible(result, format)) {
+		ast_format_cap_add(result, format);
+	}
+
+	return 0;
+}
+
+void ast_format_cap_append(struct ast_format_cap *dst, const struct ast_format_cap *src)
+{
+	ao2_callback(src->formats, OBJ_NODATA | src->nolock, append_cb, dst);
+}
+
+static int copy_cb(void *obj, void *arg, int flag)
+{
+	struct ast_format_cap *result = (struct ast_format_cap *) arg;
+	struct ast_format *format = (struct ast_format *) obj;
+
+	ast_format_cap_add(result, format);
+	return 0;
+}
+
+void ast_format_cap_copy(struct ast_format_cap *dst, const struct ast_format_cap *src)
+{
+	ast_format_cap_remove_all(dst);
+	ao2_callback(src->formats, OBJ_NODATA | src->nolock, copy_cb, dst);
+}
+
+struct ast_format_cap *ast_format_cap_dup(const struct ast_format_cap *cap)
+{
+	struct ast_format_cap *dst;
+	if (cap->nolock) {
+		dst = ast_format_cap_alloc_nolock();
+	} else {
+		dst = ast_format_cap_alloc();
+	}
+	if (!dst) {
+		return NULL;
+	}
+	ao2_callback(cap->formats, OBJ_NODATA | cap->nolock, copy_cb, dst);
+	return dst;
+}
+
+int ast_format_cap_is_empty(const struct ast_format_cap *cap)
+{
+	if (!cap) {
+		return 1;
+	}
+	return ao2_container_count(cap->formats) == 0 ? 1 : 0;
+}
+
+static int find_exact_cb(void *obj, void *arg, int flag)
+{
+	struct ast_format *format1 = (struct ast_format *) arg;
+	struct ast_format *format2 = (struct ast_format *) obj;
+
+	return (ast_format_cmp(format1, format2) == AST_FORMAT_CMP_EQUAL) ? CMP_MATCH : 0;
+}
+
+int ast_format_cap_remove(struct ast_format_cap *cap, struct ast_format *format)
+{
+	struct ast_format *fremove;
+	fremove = ao2_callback(cap->formats, OBJ_POINTER | OBJ_UNLINK | cap->nolock, find_exact_cb, format);
+
+	if (fremove) {
+		ao2_ref(fremove, -1);
+		return 0;
+	}
+
+	return -1;
+}
+
+struct multiple_by_id_data {
+	struct ast_format *format;
+	int match_found;
+};
+
+static int multiple_by_id_cb(void *obj, void *arg, int flag)
+{
+	struct multiple_by_id_data *data = arg;
+	struct ast_format *format = obj;
+	int res;
+
+	res = (format->id == data->format->id) ? CMP_MATCH : 0;
+	if (res) {
+		data->match_found = 1;
+	}
+
+	return res;
+}
+
+int ast_format_cap_remove_byid(struct ast_format_cap *cap, enum ast_format_id id)
+{
+	struct ast_format format = {
+		.id = id,
+	};
+	struct multiple_by_id_data data = {
+		.format = &format,
+		.match_found = 0,
+	};
+
+	ao2_callback(cap->formats,
+		OBJ_NODATA | cap->nolock | OBJ_MULTIPLE | OBJ_UNLINK,
+		multiple_by_id_cb,
+		&data);
+
+	/* match_found will be set if at least one item was removed */
+	if (data.match_found) {
+		return 0;
+	}
+
+	return -1;
+}
+
+static int multiple_by_type_cb(void *obj, void *arg, int flag)
+{
+	int *type = arg;
+	struct ast_format *format = obj;
+	return ((AST_FORMAT_GET_TYPE(format->id)) == *type) ? CMP_MATCH : 0;
+}
+
+void ast_format_cap_remove_bytype(struct ast_format_cap *cap, enum ast_format_type type)
+{
+	ao2_callback(cap->formats,
+		OBJ_UNLINK | OBJ_NODATA | OBJ_MULTIPLE | cap->nolock,
+		multiple_by_type_cb,
+		&type);
+}
+
+void ast_format_cap_remove_all(struct ast_format_cap *cap)
+{
+	ao2_callback(cap->formats, OBJ_NODATA | cap->nolock | OBJ_MULTIPLE | OBJ_UNLINK, NULL, NULL);
+}
+
+void ast_format_cap_set(struct ast_format_cap *cap, struct ast_format *format)
+{
+	ast_format_cap_remove_all(cap);
+	ast_format_cap_add(cap, format);
+}
+
+int ast_format_cap_iscompatible(const struct ast_format_cap *cap, const struct ast_format *format)
+{
+	struct ast_format *f;
+	struct ast_format_cap *tmp_cap = (struct ast_format_cap *) cap;
+	f = ao2_find(tmp_cap->formats, (struct ast_format *) format, OBJ_POINTER | tmp_cap->nolock);
+
+	if (f) {
+		ao2_ref(f, -1);
+		return 1;
+	}
+
+	return 0;
+}
+
+/*! \internal
+ * \brief this struct is just used for the ast_format_cap_joint function so we can provide
+ * both a format and a result ast_format_cap structure as arguments to the find_joint_cb
+ * ao2 callback function.
+ */
+struct find_joint_data {
+	/*! format to compare to for joint capabilities */
+	struct ast_format *format;
+	/*! if joint formmat exists with above format, add it to the result container */
+	struct ast_format_cap *joint_cap;
+	int joint_found;
+};
+
+static int find_joint_cb(void *obj, void *arg, int flag)
+{
+	struct ast_format *format = obj;
+	struct find_joint_data *data = arg;
+
+	struct ast_format tmp = { 0, };
+	if (!ast_format_joint(format, data->format, &tmp)) {
+		if (data->joint_cap) {
+			ast_format_cap_add(data->joint_cap, &tmp);
+		}
+		data->joint_found++;
+	}
+
+	return 0;
+}
+
+int ast_format_cap_has_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
+{
+	struct ao2_iterator it;
+	struct ast_format *tmp;
+	struct find_joint_data data = {
+		.joint_found = 0,
+		.joint_cap = NULL,
+	};
+
+	it = ao2_iterator_init(cap1->formats, cap1->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		data.format = tmp;
+		ao2_callback(cap2->formats,
+			OBJ_MULTIPLE | OBJ_NODATA | cap2->nolock,
+			find_joint_cb,
+			&data);
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	return data.joint_found ? 1 : 0;
+}
+
+int ast_format_cap_identical(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
+{
+	struct ao2_iterator it;
+	struct ast_format *tmp;
+
+	if (ao2_container_count(cap1->formats) != ao2_container_count(cap2->formats)) {
+		return 0; /* if they are not the same size, they are not identical */
+	}
+
+	it = ao2_iterator_init(cap1->formats, cap1->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		if (!ast_format_cap_iscompatible(cap2, tmp)) {
+			ao2_ref(tmp, -1);
+			ao2_iterator_destroy(&it);
+			return 0;
+		}
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	return 1;
+}
+
+struct ast_format_cap *ast_format_cap_joint(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2)
+{
+	struct ao2_iterator it;
+	struct ast_format_cap *result = ast_format_cap_alloc_nolock();
+	struct ast_format *tmp;
+	struct find_joint_data data = {
+		.joint_found = 0,
+		.joint_cap = result,
+	};
+	if (!result) {
+		return NULL;
+	}
+
+	it = ao2_iterator_init(cap1->formats, cap1->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		data.format = tmp;
+		ao2_callback(cap2->formats,
+			OBJ_MULTIPLE | OBJ_NODATA | cap2->nolock,
+			find_joint_cb,
+			&data);
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	if (ao2_container_count(result->formats)) {
+		return result;
+	}
+
+	result = ast_format_cap_destroy(result);
+	return NULL;
+}
+
+int ast_format_cap_joint_copy(const struct ast_format_cap *cap1, const struct ast_format_cap *cap2, struct ast_format_cap *result)
+{
+	struct ao2_iterator it;
+	struct ast_format *tmp;
+	struct find_joint_data data = {
+		.joint_cap = result,
+		.joint_found = 0,
+	};
+
+	ast_format_cap_remove_all(result);
+	it = ao2_iterator_init(cap1->formats, cap2->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		data.format = tmp;
+		ao2_callback(cap2->formats,
+			OBJ_MULTIPLE | OBJ_NODATA | cap2->nolock,
+			find_joint_cb,
+			&data);
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	return ao2_container_count(result->formats) ? 1 : 0;
+}
+
+struct ast_format_cap *ast_format_cap_get_type(const struct ast_format_cap *cap, enum ast_format_type ftype)
+{
+	struct ao2_iterator it;
+	struct ast_format_cap *result = ast_format_cap_alloc_nolock();
+	struct ast_format *tmp;
+
+	if (!result) {
+		return NULL;
+	}
+
+	/* for each format in cap1, see if that format is
+	 * compatible with cap2. If so copy it to the result */
+	it = ao2_iterator_init(cap->formats, cap->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		if (AST_FORMAT_GET_TYPE(tmp->id) == ftype) {
+			/* copy format */
+			ast_format_cap_add(result, tmp);
+		}
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	if (ao2_container_count(result->formats)) {
+		return result;
+	}
+	result = ast_format_cap_destroy(result);
+
+	/* Remember to always free the NULL before returning it. */
+	ast_free(NULL);
+	return NULL;
+}
+
+
+int ast_format_cap_has_type(const struct ast_format_cap *cap, enum ast_format_type type)
+{
+	struct ao2_iterator it;
+	struct ast_format *tmp;
+
+	it = ao2_iterator_init(cap->formats, cap->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		if (AST_FORMAT_GET_TYPE(tmp->id) == type) {
+			ao2_ref(tmp, -1);
+			ao2_iterator_destroy(&it);
+			return 1;
+		}
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+
+	return 0;
+}
+
+void ast_format_cap_iter_start(struct ast_format_cap *cap)
+{
+	if (!cap->nolock) {
+		ao2_lock(cap->formats);
+	}
+	cap->it = ao2_iterator_init(cap->formats, cap->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+}
+
+void ast_format_cap_iter_end(struct ast_format_cap *cap)
+{
+	ao2_iterator_destroy(&cap->it);
+	if (!cap->nolock) {
+		ao2_unlock(cap->formats);
+	}
+}
+
+int ast_format_cap_iter_next(struct ast_format_cap *cap, struct ast_format *format)
+{
+	struct ast_format *tmp = ao2_iterator_next(&cap->it);
+
+	if (!tmp) {
+		return -1;
+	}
+	ast_format_copy(format, tmp);
+	ao2_ref(tmp, -1);
+
+	return 0;
+}
+
+uint64_t ast_format_cap_to_old_bitfield(const struct ast_format_cap *cap)
+{
+	uint64_t res = 0;
+	struct ao2_iterator it;
+	struct ast_format *tmp;
+
+	it = ao2_iterator_init(cap->formats, cap->nolock ? AO2_ITERATOR_DONTLOCK : 0);
+	while ((tmp = ao2_iterator_next(&it))) {
+		res |= ast_format_to_old_bitfield(tmp);
+		ao2_ref(tmp, -1);
+	}
+	ao2_iterator_destroy(&it);
+	return res;
+}
+
+void ast_format_cap_from_old_bitfield(struct ast_format_cap *dst, uint64_t src)
+{
+	uint64_t tmp = 0;
+	int x;
+	struct ast_format tmp_format = { 0, };
+
+	ast_format_cap_remove_all(dst);
+	for (x = 0; x < 64; x++) {
+		tmp = (1ULL << x);
+		if (tmp & src) {
+			ast_format_cap_add(dst, ast_format_from_old_bitfield(&tmp_format, tmp));
+		}
+	}
+}
diff --git a/main/format_pref.c b/main/format_pref.c
new file mode 100644
index 0000000000000000000000000000000000000000..26801b648d0268068f03c34cbc3c2f5bc3d78ec4
--- /dev/null
+++ b/main/format_pref.c
@@ -0,0 +1,320 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * Mark Spencer <markster@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Format Preference API
+ */
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$");
+
+#include "asterisk/_private.h"
+#include "asterisk/version.h"
+#include "asterisk/frame.h"
+#include "asterisk/channel.h"
+#include "asterisk/utils.h"
+
+void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right)
+{
+	size_t f_len;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+	int x, differential = (int) 'A', mem;
+	char *from, *to;
+
+	/* TODO re-evaluate this function.  It is using the order of the formats specified
+	 * in the global format list in a way that may not be safe. */
+	if (right) {
+		from = pref->order;
+		to = buf;
+		mem = size;
+	} else {
+		to = pref->order;
+		from = buf;
+		mem = AST_CODEC_PREF_SIZE;
+	}
+
+	memset(to, 0, mem);
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!from[x]) {
+			break;
+		}
+		to[x] = right ? (from[x] + differential) : (from[x] - differential);
+		if (!right && to[x] && (to[x] < f_len)) {
+			ast_format_set(&pref->formats[x], f_list[to[x]-1].id , 0);
+		}
+	}
+}
+
+int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size)
+{
+	int x;
+	struct ast_format format;
+	size_t total_len, slen;
+	char *formatname;
+
+	memset(buf, 0, size);
+	total_len = size;
+	buf[0] = '(';
+	total_len--;
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (total_len <= 0)
+			break;
+		if (!(ast_codec_pref_index(pref, x, &format)))
+			break;
+		if ((formatname = ast_getformatname(&format))) {
+			slen = strlen(formatname);
+			if (slen > total_len)
+				break;
+			strncat(buf, formatname, total_len - 1); /* safe */
+			total_len -= slen;
+		}
+		if (total_len && x < AST_CODEC_PREF_SIZE - 1 && ast_codec_pref_index(pref, x + 1, &format)) {
+			strncat(buf, "|", total_len - 1); /* safe */
+			total_len--;
+		}
+	}
+	if (total_len) {
+		strncat(buf, ")", total_len - 1); /* safe */
+		total_len--;
+	}
+
+	return size - total_len;
+}
+
+struct ast_format *ast_codec_pref_index(struct ast_codec_pref *pref, int idx, struct ast_format *result)
+{
+	if ((idx >= 0) && (idx < sizeof(pref->order)) && pref->formats[idx].id) {
+		ast_format_copy(result, &pref->formats[idx]);
+	} else {
+		ast_format_clear(result);
+		return NULL;
+	}
+
+	return result;
+}
+
+/*! \brief Remove codec from pref list */
+void ast_codec_pref_remove(struct ast_codec_pref *pref, struct ast_format *format)
+{
+	struct ast_codec_pref oldorder;
+	int x, y = 0;
+	size_t f_len = 0;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	if (!pref->order[0])
+		return;
+
+	memcpy(&oldorder, pref, sizeof(oldorder));
+	memset(pref, 0, sizeof(*pref));
+
+	for (x = 0; x < f_len; x++) {
+		if (!oldorder.order[x])
+			break;
+		if (f_list[oldorder.order[x]-1].id != format->id) {
+			pref->order[y] = oldorder.order[x];
+			ast_format_copy(&pref->formats[y], &oldorder.formats[x]);
+			pref->framing[y++] = oldorder.framing[x];
+		}
+	}
+}
+
+/*! \brief Append codec to list */
+int ast_codec_pref_append(struct ast_codec_pref *pref, struct ast_format *format)
+{
+	int x, newindex = 0;
+	size_t f_len = 0;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	ast_codec_pref_remove(pref, format);
+
+	for (x = 0; x < f_len; x++) {
+		if (f_list[x].id == format->id) {
+			newindex = x + 1;
+			break;
+		}
+	}
+
+	if (newindex) {
+		for (x = 0; x < f_len; x++) {
+			if (!pref->order[x]) {
+				pref->order[x] = newindex;
+				ast_format_copy(&pref->formats[x], format);
+				break;
+			}
+		}
+	}
+
+	return x;
+}
+
+/*! \brief Prepend codec to list */
+void ast_codec_pref_prepend(struct ast_codec_pref *pref, struct ast_format *format, int only_if_existing)
+{
+	int x, newindex = 0;
+	size_t f_len = 0;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	/* First step is to get the codecs "index number" */
+	for (x = 0; x < f_len; x++) {
+		if (f_list[x].id == format->id) {
+			newindex = x + 1;
+			break;
+		}
+	}
+	/* Done if its unknown */
+	if (!newindex)
+		return;
+
+	/* Now find any existing occurrence, or the end */
+	for (x = 0; x < AST_CODEC_PREF_SIZE; x++) {
+		if (!pref->order[x] || pref->order[x] == newindex)
+			break;
+	}
+
+	if (only_if_existing && !pref->order[x])
+		return;
+
+	/* Move down to make space to insert - either all the way to the end,
+	   or as far as the existing location (which will be overwritten) */
+	for (; x > 0; x--) {
+		pref->order[x] = pref->order[x - 1];
+		pref->framing[x] = pref->framing[x - 1];
+		ast_format_copy(&pref->formats[x], &pref->formats[x - 1]);
+	}
+
+	/* And insert the new entry */
+	pref->order[0] = newindex;
+	pref->framing[0] = 0; /* ? */
+	ast_format_copy(&pref->formats[0], format);
+}
+
+/*! \brief Set packet size for codec */
+int ast_codec_pref_setsize(struct ast_codec_pref *pref, struct ast_format *format, int framems)
+{
+	int x, idx = -1;
+	size_t f_len = 0;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	for (x = 0; x < f_len; x++) {
+		if (f_list[x].id == format->id) {
+			idx = x;
+			break;
+		}
+	}
+
+	if (idx < 0)
+		return -1;
+
+	/* size validation */
+	if (!framems)
+		framems = f_list[idx].def_ms;
+
+	if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */
+		framems -= framems % f_list[idx].inc_ms;
+
+	if (framems < f_list[idx].min_ms)
+		framems = f_list[idx].min_ms;
+
+	if (framems > f_list[idx].max_ms)
+		framems = f_list[idx].max_ms;
+
+	for (x = 0; x < f_len; x++) {
+		if (pref->order[x] == (idx + 1)) {
+			pref->framing[x] = framems;
+			break;
+		}
+	}
+
+	return x;
+}
+
+/*! \brief Get packet size for codec */
+struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, struct ast_format *format)
+{
+	int x, idx = -1, framems = 0;
+	struct ast_format_list fmt = { 0, };
+	size_t f_len = 0;
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	for (x = 0; x < f_len; x++) {
+		if (f_list[x].id == format->id) {
+			fmt = f_list[x];
+			idx = x;
+			break;
+		}
+	}
+
+	for (x = 0; x < f_len; x++) {
+		if (pref->order[x] == (idx + 1)) {
+			framems = pref->framing[x];
+			break;
+		}
+	}
+
+	/* size validation */
+	if (!framems)
+		framems = f_list[idx].def_ms;
+
+	if (f_list[idx].inc_ms && framems % f_list[idx].inc_ms) /* avoid division by zero */
+		framems -= framems % f_list[idx].inc_ms;
+
+	if (framems < f_list[idx].min_ms)
+		framems = f_list[idx].min_ms;
+
+	if (framems > f_list[idx].max_ms)
+		framems = f_list[idx].max_ms;
+
+	fmt.cur_ms = framems;
+
+	return fmt;
+}
+
+/*! \brief Pick a codec */
+struct ast_format *ast_codec_choose(struct ast_codec_pref *pref, struct ast_format_cap *cap, int find_best, struct ast_format *result)
+{
+	int x, slot, found;
+	size_t f_len = 0;
+	struct ast_format tmp_fmt;
+
+	const struct ast_format_list *f_list = ast_get_format_list(&f_len);
+
+	ast_format_clear(result);
+
+	for (x = 0; x < f_len; x++) {
+		slot = pref->order[x];
+
+		if (!slot)
+			break;
+		if (ast_format_cap_iscompatible(cap, ast_format_set(&tmp_fmt, f_list[slot-1].id, 0))) {
+			found = 1; /*format is found and stored in tmp_fmt */
+			break;
+		}
+	}
+	if (found && (AST_FORMAT_GET_TYPE(tmp_fmt.id) == AST_FORMAT_TYPE_AUDIO)) {
+		ast_format_copy(result, &tmp_fmt);
+		return result;
+	}
+
+	ast_debug(4, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
+
+	return find_best ? ast_best_codec(cap, result) : NULL;
+}
+
+
diff --git a/main/frame.c b/main/frame.c
index 9f599a9917937062e3e381861ca186598f2bbba7..840fa4b75da4e78654a28941ec90b9acf5a501e4 100644
--- a/main/frame.c
+++ b/main/frame.c
@@ -80,7 +80,7 @@ enum frame_type {
 
 struct ast_smoother {
 	int size;
-	format_t format;
+	struct ast_format format;
 	int flags;
 	float samplesperbyte;
 	unsigned int opt_needs_swap:1;
@@ -207,12 +207,12 @@ int __ast_smoother_feed(struct ast_smoother *s, struct ast_frame *f, int swap)
 		ast_log(LOG_WARNING, "Huh?  Can't smooth a non-voice frame!\n");
 		return -1;
 	}
-	if (!s->format) {
-		s->format = f->subclass.codec;
+	if (!s->format.id) {
+		ast_format_copy(&s->format, &f->subclass.format);
 		s->samplesperbyte = (float)f->samples / (float)f->datalen;
-	} else if (s->format != f->subclass.codec) {
+	} else if (ast_format_cmp(&s->format, &f->subclass.format) == AST_FORMAT_CMP_NOT_EQUAL) {
 		ast_log(LOG_WARNING, "Smoother was working on %s format frames, now trying to feed %s?\n",
-			ast_getformatname(s->format), ast_getformatname(f->subclass.codec));
+			ast_getformatname(&s->format), ast_getformatname(&f->subclass.format));
 		return -1;
 	}
 	if (s->len + f->datalen > SMOOTHER_SIZE) {
@@ -263,7 +263,7 @@ struct ast_frame *ast_smoother_read(struct ast_smoother *s)
 		len = s->len;
 	/* Make frame */
 	s->f.frametype = AST_FRAME_VOICE;
-	s->f.subclass.codec = s->format;
+	ast_format_copy(&s->f.subclass.format, &s->format);
 	s->f.data.ptr = s->framedata + AST_FRIENDLY_OFFSET;
 	s->f.offset = AST_FRIENDLY_OFFSET;
 	s->f.datalen = len;
@@ -280,7 +280,7 @@ struct ast_frame *ast_smoother_read(struct ast_smoother *s)
 		memmove(s->data, s->data + len, s->len);
 		if (!ast_tvzero(s->delivery)) {
 			/* If we have delivery time, increment it, otherwise, leave it at 0 */
-			s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, ast_format_rate(s->format)));
+			s->delivery = ast_tvadd(s->delivery, ast_samp2tv(s->f.samples, ast_format_rate(&s->format)));
 		}
 	}
 	/* Return frame */
@@ -408,7 +408,7 @@ struct ast_frame *ast_frisolate(struct ast_frame *fr)
 			return NULL;
 		}
 		out->frametype = fr->frametype;
-		out->subclass.codec = fr->subclass.codec;
+		ast_format_copy(&out->subclass.format, &fr->subclass.format);
 		out->datalen = fr->datalen;
 		out->samples = fr->samples;
 		out->offset = fr->offset;
@@ -515,7 +515,7 @@ struct ast_frame *ast_frdup(const struct ast_frame *f)
 	}
 
 	out->frametype = f->frametype;
-	out->subclass.codec = f->subclass.codec;
+	ast_format_copy(&out->subclass.format, &f->subclass.format);
 	out->datalen = f->datalen;
 	out->samples = f->samples;
 	out->delivery = f->delivery;
@@ -566,12 +566,12 @@ const struct ast_format_list *ast_get_format_list(size_t *size)
 	return AST_FORMAT_LIST;
 }
 
-char* ast_getformatname(format_t format)
+char* ast_getformatname(struct ast_format *format)
 {
 	int x;
 	char *ret = "unknown";
 	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == format) {
+		if (AST_FORMAT_LIST[x].id == format->id) {
 			ret = AST_FORMAT_LIST[x].name;
 			break;
 		}
@@ -579,21 +579,23 @@ char* ast_getformatname(format_t format)
 	return ret;
 }
 
-char *ast_getformatname_multiple(char *buf, size_t size, format_t format)
+char *ast_getformatname_multiple(char *buf, size_t size, struct ast_format_cap *cap)
 {
 	int x;
 	unsigned len;
 	char *start, *end = buf;
+	struct ast_format tmp_fmt;
 
 	if (!size)
 		return buf;
-	snprintf(end, size, "0x%llx (", (unsigned long long) format);
+	snprintf(end, size, "(");
 	len = strlen(end);
 	end += len;
 	size -= len;
 	start = end;
 	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits & format) {
+		ast_format_set(&tmp_fmt, AST_FORMAT_LIST[x].id, 0);
+		if (ast_format_cap_iscompatible(cap, &tmp_fmt)) {
 			snprintf(end, size, "%s|", AST_FORMAT_LIST[x].name);
 			len = strlen(end);
 			end += len;
@@ -629,31 +631,28 @@ static const char *ast_expand_codec_alias(const char *in)
 	return in;
 }
 
-format_t ast_getformatbyname(const char *name)
+struct ast_format *ast_getformatbyname(const char *name, struct ast_format *result)
 {
-	int x, all;
-	format_t format = 0;
+	int x;
 
-	all = strcasecmp(name, "all") ? 0 : 1;
 	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (all || 
-			  !strcasecmp(AST_FORMAT_LIST[x].name,name) ||
-			  !strcasecmp(AST_FORMAT_LIST[x].name, ast_expand_codec_alias(name))) {
-			format |= AST_FORMAT_LIST[x].bits;
-			if (!all)
-				break;
+		if (!strcasecmp(AST_FORMAT_LIST[x].name,name) ||
+			 !strcasecmp(AST_FORMAT_LIST[x].name, ast_expand_codec_alias(name))) {
+
+			ast_format_set(result, AST_FORMAT_LIST[x].id, 0);
+			return result;
 		}
 	}
 
-	return format;
+	return NULL;
 }
 
-char *ast_codec2str(format_t codec)
+char *ast_codec2str(struct ast_format *format)
 {
 	int x;
 	char *ret = "unknown";
 	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == codec) {
+		if (AST_FORMAT_LIST[x].id == format->id) {
 			ret = AST_FORMAT_LIST[x].desc;
 			break;
 		}
@@ -663,8 +662,7 @@ char *ast_codec2str(format_t codec)
 
 static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	int i, found=0;
-	char hex[25];
+	int x, found=0;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -684,25 +682,25 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
 		ast_cli(a->fd, "Disclaimer: this command is for informational purposes only.\n"
 				"\tIt does not indicate anything about your configuration.\n");
 
-	ast_cli(a->fd, "%19s %9s %20s   TYPE   %8s   %s\n","INT","BINARY","HEX","NAME","DESCRIPTION");
+	ast_cli(a->fd, "%19s %8s %8s %s\n","ID","TYPE","NAME","DESCRIPTION");
 	ast_cli(a->fd, "-----------------------------------------------------------------------------------\n");
-	for (i = 0; i < 63; i++) {
 
+	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
 		if (a->argc == 4) {
 			if (!strcasecmp(a->argv[3], "audio")) {
-				if (!((1LL << i) & AST_FORMAT_AUDIO_MASK)) {
+				if (AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id) != AST_FORMAT_TYPE_AUDIO) {
 					continue;
 				}
 			} else if (!strcasecmp(a->argv[3], "video")) {
-				if (!((1LL << i) & AST_FORMAT_VIDEO_MASK)) {
+				if (AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id) != AST_FORMAT_TYPE_VIDEO) {
 					continue;
 				}
 			} else if (!strcasecmp(a->argv[3], "image")) {
-				if (i != 16 && i != 17) {
+				if (AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id) != AST_FORMAT_TYPE_IMAGE) {
 					continue;
 				}
 			} else if (!strcasecmp(a->argv[3], "text")) {
-				if (!((1LL << i) & AST_FORMAT_TEXT_MASK)) {
+				if (AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id) != AST_FORMAT_TYPE_TEXT) {
 					continue;
 				}
 			} else {
@@ -710,14 +708,15 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
 			}
 		}
 
-		snprintf(hex, sizeof(hex), "(0x%llx)", 1LL << i);
-		ast_cli(a->fd, "%19llu (1 << %2d) %20s  %5s   %8s   (%s)\n", 1LL << i, i, hex,
-			((1LL << i) & AST_FORMAT_AUDIO_MASK) ? "audio" :
-			i == 16 || i == 17 ? "image" :
-			((1LL << i) & AST_FORMAT_VIDEO_MASK) ? "video" :
-			((1LL << i) & AST_FORMAT_TEXT_MASK) ? "text" :
+		ast_cli(a->fd, "%19u %5s %8s (%s)\n",
+			AST_FORMAT_LIST[x].id,
+			(AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id) == AST_FORMAT_TYPE_AUDIO) ? "audio" :
+			(AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id)  == AST_FORMAT_TYPE_TEXT)  ? "image" :
+			(AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id)  == AST_FORMAT_TYPE_VIDEO) ? "video" :
+			(AST_FORMAT_GET_TYPE(AST_FORMAT_LIST[x].id)  == AST_FORMAT_TYPE_TEXT)  ? "text"  :
 			"(unk)",
-			ast_getformatname(1LL << i), ast_codec2str(1LL << i));
+			AST_FORMAT_LIST[x].name,
+			AST_FORMAT_LIST[x].desc);
 		found = 1;
 	}
 
@@ -730,9 +729,9 @@ static char *show_codecs(struct ast_cli_entry *e, int cmd, struct ast_cli_args *
 
 static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 {
-	format_t codec;
-	int i, found = 0;
-	long long type_punned_codec;
+	enum ast_format_id format_id;
+	int x, found = 0;
+	int type_punned_codec;
 
 	switch (cmd) {
 	case CLI_INIT:
@@ -748,19 +747,21 @@ static char *show_codec_n(struct ast_cli_entry *e, int cmd, struct ast_cli_args
 	if (a->argc != 4)
 		return CLI_SHOWUSAGE;
 
-	if (sscanf(a->argv[3], "%30lld", &type_punned_codec) != 1) {
+	if (sscanf(a->argv[3], "%30d", &type_punned_codec) != 1) {
 		return CLI_SHOWUSAGE;
 	}
-	codec = type_punned_codec;
+	format_id = type_punned_codec;
 
-	for (i = 0; i < 63; i++)
-		if (codec & (1LL << i)) {
+	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
+		if (AST_FORMAT_LIST[x].id == format_id) {
 			found = 1;
-			ast_cli(a->fd, "%11llu (1 << %2d)  %s\n", 1LL << i, i, ast_codec2str(1LL << i));
+			ast_cli(a->fd, "%11u %s\n", (unsigned int) format_id, AST_FORMAT_LIST[x].desc);
+			break;
 		}
+	}
 
 	if (!found)
-		ast_cli(a->fd, "Codec %lld not found\n", (long long) codec);
+		ast_cli(a->fd, "Codec %d not found\n", format_id);
 
 	return CLI_SUCCESS;
 }
@@ -896,7 +897,7 @@ void ast_frame_dump(const char *name, struct ast_frame *f, char *prefix)
 		break;
 	case AST_FRAME_IMAGE:
 		strcpy(ftype, "Image");
-		snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(f->subclass.codec));
+		snprintf(subclass, sizeof(subclass), "Image format %s\n", ast_getformatname(&f->subclass.format));
 		break;
 	case AST_FRAME_HTML:
 		strcpy(ftype, "HTML");
@@ -984,271 +985,11 @@ int init_framer(void)
 	return 0;	
 }
 
-void ast_codec_pref_convert(struct ast_codec_pref *pref, char *buf, size_t size, int right) 
-{
-	int x, differential = (int) 'A', mem;
-	char *from, *to;
-
-	if (right) {
-		from = pref->order;
-		to = buf;
-		mem = size;
-	} else {
-		to = pref->order;
-		from = buf;
-		mem = sizeof(format_t) * 8;
-	}
-
-	memset(to, 0, mem);
-	for (x = 0; x < sizeof(format_t) * 8; x++) {
-		if (!from[x])
-			break;
-		to[x] = right ? (from[x] + differential) : (from[x] - differential);
-	}
-}
-
-int ast_codec_pref_string(struct ast_codec_pref *pref, char *buf, size_t size) 
-{
-	int x;
-	format_t codec; 
-	size_t total_len, slen;
-	char *formatname;
-	
-	memset(buf, 0, size);
-	total_len = size;
-	buf[0] = '(';
-	total_len--;
-	for (x = 0; x < sizeof(format_t) * 8; x++) {
-		if (total_len <= 0)
-			break;
-		if (!(codec = ast_codec_pref_index(pref,x)))
-			break;
-		if ((formatname = ast_getformatname(codec))) {
-			slen = strlen(formatname);
-			if (slen > total_len)
-				break;
-			strncat(buf, formatname, total_len - 1); /* safe */
-			total_len -= slen;
-		}
-		if (total_len && x < sizeof(format_t) * 8 - 1 && ast_codec_pref_index(pref, x + 1)) {
-			strncat(buf, "|", total_len - 1); /* safe */
-			total_len--;
-		}
-	}
-	if (total_len) {
-		strncat(buf, ")", total_len - 1); /* safe */
-		total_len--;
-	}
-
-	return size - total_len;
-}
-
-format_t ast_codec_pref_index(struct ast_codec_pref *pref, int idx)
-{
-	int slot = 0;
-
-	if ((idx >= 0) && (idx < sizeof(pref->order))) {
-		slot = pref->order[idx];
-	}
-
-	return slot ? AST_FORMAT_LIST[slot - 1].bits : 0;
-}
-
-/*! \brief Remove codec from pref list */
-void ast_codec_pref_remove(struct ast_codec_pref *pref, format_t format)
-{
-	struct ast_codec_pref oldorder;
-	int x, y = 0;
-	int slot;
-	int size;
-
-	if (!pref->order[0])
-		return;
-
-	memcpy(&oldorder, pref, sizeof(oldorder));
-	memset(pref, 0, sizeof(*pref));
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		slot = oldorder.order[x];
-		size = oldorder.framing[x];
-		if (! slot)
-			break;
-		if (AST_FORMAT_LIST[slot-1].bits != format) {
-			pref->order[y] = slot;
-			pref->framing[y++] = size;
-		}
-	}
-}
-
-/*! \brief Append codec to list */
-int ast_codec_pref_append(struct ast_codec_pref *pref, format_t format)
-{
-	int x, newindex = 0;
-
-	ast_codec_pref_remove(pref, format);
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == format) {
-			newindex = x + 1;
-			break;
-		}
-	}
-
-	if (newindex) {
-		for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-			if (!pref->order[x]) {
-				pref->order[x] = newindex;
-				break;
-			}
-		}
-	}
-
-	return x;
-}
-
-/*! \brief Prepend codec to list */
-void ast_codec_pref_prepend(struct ast_codec_pref *pref, format_t format, int only_if_existing)
+int ast_parse_allow_disallow(struct ast_codec_pref *pref, struct ast_format_cap *cap, const char *list, int allowing) 
 {
-	int x, newindex = 0;
-
-	/* First step is to get the codecs "index number" */
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == format) {
-			newindex = x + 1;
-			break;
-		}
-	}
-	/* Done if its unknown */
-	if (!newindex)
-		return;
-
-	/* Now find any existing occurrence, or the end */
-	for (x = 0; x < sizeof(format_t) * 8; x++) {
-		if (!pref->order[x] || pref->order[x] == newindex)
-			break;
-	}
-
-	if (only_if_existing && !pref->order[x])
-		return;
-
-	/* Move down to make space to insert - either all the way to the end,
-	   or as far as the existing location (which will be overwritten) */
-	for (; x > 0; x--) {
-		pref->order[x] = pref->order[x - 1];
-		pref->framing[x] = pref->framing[x - 1];
-	}
-
-	/* And insert the new entry */
-	pref->order[0] = newindex;
-	pref->framing[0] = 0; /* ? */
-}
-
-/*! \brief Set packet size for codec */
-int ast_codec_pref_setsize(struct ast_codec_pref *pref, format_t format, int framems)
-{
-	int x, idx = -1;
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == format) {
-			idx = x;
-			break;
-		}
-	}
-
-	if (idx < 0)
-		return -1;
-
-	/* size validation */
-	if (!framems)
-		framems = AST_FORMAT_LIST[idx].def_ms;
-
-	if (AST_FORMAT_LIST[idx].inc_ms && framems % AST_FORMAT_LIST[idx].inc_ms) /* avoid division by zero */
-		framems -= framems % AST_FORMAT_LIST[idx].inc_ms;
-
-	if (framems < AST_FORMAT_LIST[idx].min_ms)
-		framems = AST_FORMAT_LIST[idx].min_ms;
-
-	if (framems > AST_FORMAT_LIST[idx].max_ms)
-		framems = AST_FORMAT_LIST[idx].max_ms;
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (pref->order[x] == (idx + 1)) {
-			pref->framing[x] = framems;
-			break;
-		}
-	}
-
-	return x;
-}
-
-/*! \brief Get packet size for codec */
-struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, format_t format)
-{
-	int x, idx = -1, framems = 0;
-	struct ast_format_list fmt = { 0, };
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (AST_FORMAT_LIST[x].bits == format) {
-			fmt = AST_FORMAT_LIST[x];
-			idx = x;
-			break;
-		}
-	}
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		if (pref->order[x] == (idx + 1)) {
-			framems = pref->framing[x];
-			break;
-		}
-	}
-
-	/* size validation */
-	if (!framems)
-		framems = AST_FORMAT_LIST[idx].def_ms;
-
-	if (AST_FORMAT_LIST[idx].inc_ms && framems % AST_FORMAT_LIST[idx].inc_ms) /* avoid division by zero */
-		framems -= framems % AST_FORMAT_LIST[idx].inc_ms;
-
-	if (framems < AST_FORMAT_LIST[idx].min_ms)
-		framems = AST_FORMAT_LIST[idx].min_ms;
-
-	if (framems > AST_FORMAT_LIST[idx].max_ms)
-		framems = AST_FORMAT_LIST[idx].max_ms;
-
-	fmt.cur_ms = framems;
-
-	return fmt;
-}
-
-/*! \brief Pick a codec */
-format_t ast_codec_choose(struct ast_codec_pref *pref, format_t formats, int find_best)
-{
-	int x, slot;
-	format_t ret = 0;
-
-	for (x = 0; x < ARRAY_LEN(AST_FORMAT_LIST); x++) {
-		slot = pref->order[x];
-
-		if (!slot)
-			break;
-		if (formats & AST_FORMAT_LIST[slot-1].bits) {
-			ret = AST_FORMAT_LIST[slot-1].bits;
-			break;
-		}
-	}
-	if (ret & AST_FORMAT_AUDIO_MASK)
-		return ret;
-
-	ast_debug(4, "Could not find preferred codec - %s\n", find_best ? "Going for the best codec" : "Returning zero codec");
-
-   	return find_best ? ast_best_codec(formats) : 0;
-}
-
-int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const char *list, int allowing) 
-{
-	int errors = 0, framems = 0;
+	int errors = 0, framems = 0, all = 0;
 	char *parse = NULL, *this = NULL, *psize = NULL;
-	format_t format = 0;
+	struct ast_format format;
 
 	parse = ast_strdupa(list);
 	while ((this = strsep(&parse, ","))) {
@@ -1263,30 +1004,38 @@ int ast_parse_allow_disallow(struct ast_codec_pref *pref, format_t *mask, const
 				ast_log(LOG_WARNING, "Bad packetization value for codec %s\n", this);
 			}
 		}
-		if (!(format = ast_getformatbyname(this))) {
+		all = strcasecmp(this, "all") ? 0 : 1;
+
+		if (!all && !ast_getformatbyname(this, &format)) {
 			ast_log(LOG_WARNING, "Cannot %s unknown format '%s'\n", allowing ? "allow" : "disallow", this);
 			errors++;
 			continue;
 		}
 
-		if (mask) {
-			if (allowing)
-				*mask |= format;
-			else
-				*mask &= ~format;
+		if (cap) {
+			if (allowing) {
+				if (all) {
+					ast_format_cap_add_all(cap);
+				} else {
+					ast_format_cap_add(cap, &format);
+				}
+			} else {
+				if (all) {
+					ast_format_cap_remove_all(cap);
+				} else {
+					ast_format_cap_remove(cap, &format);
+				}
+			}
 		}
 
-		/* Set up a preference list for audio. Do not include video in preferences 
-		   since we can not transcode video and have to use whatever is offered
-		 */
-		if (pref && (format & AST_FORMAT_AUDIO_MASK)) {
-			if (strcasecmp(this, "all")) {
+		if (pref) {
+			if (!all) {
 				if (allowing) {
-					ast_codec_pref_append(pref, format);
-					ast_codec_pref_setsize(pref, format, framems);
+					ast_codec_pref_append(pref, &format);
+					ast_codec_pref_setsize(pref, &format, framems);
+				} else {
+					ast_codec_pref_remove(pref, &format);
 				}
-				else
-					ast_codec_pref_remove(pref, format);
 			} else if (!allowing) {
 				memset(pref, 0, sizeof(*pref));
 			}
@@ -1445,9 +1194,8 @@ static int speex_samples(unsigned char *data, int len)
 int ast_codec_get_samples(struct ast_frame *f)
 {
 	int samples = 0;
-	char tmp[64];
 
-	switch (f->subclass.codec) {
+	switch (f->subclass.format.id) {
 	case AST_FORMAT_SPEEX:
 		samples = speex_samples(f->data.ptr, f->datalen);
 		break;
@@ -1499,17 +1247,17 @@ int ast_codec_get_samples(struct ast_frame *f)
 		samples = (int) f->datalen * ((float) 48000 / 8000);
 		break;
 	default:
-		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname_multiple(tmp, sizeof(tmp), f->subclass.codec));
+		ast_log(LOG_WARNING, "Unable to calculate samples for format %s\n", ast_getformatname(&f->subclass.format));
 	}
 	return samples;
 }
 
-int ast_codec_get_len(format_t format, int samples)
+int ast_codec_get_len(struct ast_format *format, int samples)
 {
 	int len = 0;
 
 	/* XXX Still need speex, and lpc10 XXX */	
-	switch(format) {
+	switch(format->id) {
 	case AST_FORMAT_G723_1:
 		len = (samples / 240) * 20;
 		break;
@@ -1562,7 +1310,7 @@ int ast_frame_adjust_volume(struct ast_frame *f, int adjustment)
 	short *fdata = f->data.ptr;
 	short adjust_value = abs(adjustment);
 
-	if ((f->frametype != AST_FRAME_VOICE) || (f->subclass.codec != AST_FORMAT_SLINEAR))
+	if ((f->frametype != AST_FRAME_VOICE) || (f->subclass.format.id != AST_FORMAT_SLINEAR))
 		return -1;
 
 	if (!adjustment)
@@ -1584,10 +1332,10 @@ int ast_frame_slinear_sum(struct ast_frame *f1, struct ast_frame *f2)
 	int count;
 	short *data1, *data2;
 
-	if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass.codec != AST_FORMAT_SLINEAR))
+	if ((f1->frametype != AST_FRAME_VOICE) || (f1->subclass.format.id != AST_FORMAT_SLINEAR))
 		return -1;
 
-	if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass.codec != AST_FORMAT_SLINEAR))
+	if ((f2->frametype != AST_FRAME_VOICE) || (f2->subclass.format.id != AST_FORMAT_SLINEAR))
 		return -1;
 
 	if (f1->samples != f2->samples)
diff --git a/main/image.c b/main/image.c
index 5da07ce069c7ae3f03e36f5c2251eb6be5494000..3aa22665327a7089a7f88cb8a2fd763617aa4bef 100644
--- a/main/image.c
+++ b/main/image.c
@@ -96,7 +96,7 @@ static void make_filename(char *buf, int len, const char *filename, const char *
 	}
 }
 
-struct ast_frame *ast_read_image(const char *filename, const char *preflang, int format)
+struct ast_frame *ast_read_image(const char *filename, const char *preflang, struct ast_format *format)
 {
 	struct ast_imager *i;
 	char buf[256];
@@ -109,7 +109,8 @@ struct ast_frame *ast_read_image(const char *filename, const char *preflang, int
 	
 	AST_RWLIST_RDLOCK(&imagers);
 	AST_RWLIST_TRAVERSE(&imagers, i, list) {
-		if (i->format & format) {
+		/* if NULL image format, just pick the first one, otherwise match it. */
+		if (!format || (ast_format_cmp(&i->format, format) == AST_FORMAT_CMP_EQUAL)) {
 			char *stringp=NULL;
 			ast_copy_string(tmp, i->exts, sizeof(tmp));
 			stringp = tmp;
@@ -157,7 +158,7 @@ int ast_send_image(struct ast_channel *chan, const char *filename)
 	struct ast_frame *f;
 	int res = -1;
 	if (chan->tech->send_image) {
-		f = ast_read_image(filename, chan->language, -1);
+		f = ast_read_image(filename, chan->language, NULL);
 		if (f) {
 			res = chan->tech->send_image(chan, f);
 			ast_frfree(f);
@@ -189,7 +190,7 @@ static char *handle_core_show_image_formats(struct ast_cli_entry *e, int cmd, st
 	ast_cli(a->fd, FORMAT, "----", "----------", "-----------", "------");
 	AST_RWLIST_RDLOCK(&imagers);
 	AST_RWLIST_TRAVERSE(&imagers, i, list) {
-		ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(i->format));
+		ast_cli(a->fd, FORMAT2, i->name, i->exts, i->desc, ast_getformatname(&i->format));
 		count_fmt++;
 	}
 	AST_RWLIST_UNLOCK(&imagers);
diff --git a/main/indications.c b/main/indications.c
index dcd597ac7a0e65888a7860aa0f18c9825ae61881..f93239380a922e2639acc32e6928ef9d3ac824f4 100644
--- a/main/indications.c
+++ b/main/indications.c
@@ -116,7 +116,7 @@ struct playtones_state {
 	int npos;
 	int oldnpos;
 	int pos;
-	int origwfmt;
+	struct ast_format origwfmt;
 	struct ast_frame f;
 	unsigned char offset[AST_FRIENDLY_OFFSET];
 	short data[4000];
@@ -127,7 +127,7 @@ static void playtones_release(struct ast_channel *chan, void *params)
 	struct playtones_state *ps = params;
 
 	if (chan) {
-		ast_set_write_format(chan, ps->origwfmt);
+		ast_set_write_format(chan, &ps->origwfmt);
 	}
 
 	if (ps->items) {
@@ -147,9 +147,9 @@ static void *playtones_alloc(struct ast_channel *chan, void *params)
 		return NULL;
 	}
 
-	ps->origwfmt = chan->writeformat;
+	ast_format_copy(&ps->origwfmt, &chan->writeformat);
 
-	if (ast_set_write_format(chan, AST_FORMAT_SLINEAR)) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_log(LOG_WARNING, "Unable to set '%s' to signed linear format (write)\n", chan->name);
 		playtones_release(NULL, ps);
 		ps = NULL;
@@ -223,7 +223,7 @@ static int playtones_generator(struct ast_channel *chan, void *data, int len, in
 	}
 
 	ps->f.frametype = AST_FRAME_VOICE;
-	ps->f.subclass.codec = AST_FORMAT_SLINEAR;
+	ast_format_set(&ps->f.subclass.format, AST_FORMAT_SLINEAR, 0);
 	ps->f.datalen = len;
 	ps->f.samples = samples;
 	ps->f.offset = AST_FRIENDLY_OFFSET;
diff --git a/main/manager.c b/main/manager.c
index 40804bf31187d924cefda6622df50d8a865e8eea..27fa6d8dd0fc4a41ebef4da2ec1e74a8949cd21a 100644
--- a/main/manager.c
+++ b/main/manager.c
@@ -3506,7 +3506,7 @@ struct fast_originate_helper {
 	/*! data can contain a channel name, extension number, username, password, etc. */
 	char data[512];
 	int timeout;
-	format_t format;				/*!< Codecs used for a call */
+	struct ast_format_cap *cap;				/*!< Codecs used for a call */
 	char app[AST_MAX_APP];
 	char appdata[AST_MAX_EXTENSION];
 	char cid_name[AST_MAX_EXTENSION];
@@ -3528,12 +3528,12 @@ static void *fast_originate(void *data)
 	char requested_channel[AST_CHANNEL_NAME];
 
 	if (!ast_strlen_zero(in->app)) {
-		res = ast_pbx_outgoing_app(in->tech, in->format, in->data, in->timeout, in->app, in->appdata, &reason, 1,
+		res = ast_pbx_outgoing_app(in->tech, in->cap, in->data, in->timeout, in->app, in->appdata, &reason, 1,
 			S_OR(in->cid_num, NULL),
 			S_OR(in->cid_name, NULL),
 			in->vars, in->account, &chan);
 	} else {
-		res = ast_pbx_outgoing_exten(in->tech, in->format, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
+		res = ast_pbx_outgoing_exten(in->tech, in->cap, in->data, in->timeout, in->context, in->exten, in->priority, &reason, 1,
 			S_OR(in->cid_num, NULL),
 			S_OR(in->cid_name, NULL),
 			in->vars, in->account, &chan);
@@ -3565,6 +3565,7 @@ static void *fast_originate(void *data)
 	if (chan) {
 		ast_channel_unlock(chan);
 	}
+	in->cap = ast_format_cap_destroy(in->cap);
 	ast_free(in);
 	return NULL;
 }
@@ -3822,29 +3823,39 @@ static int action_originate(struct mansession *s, const struct message *m)
 	int reason = 0;
 	char tmp[256];
 	char tmp2[256];
-	format_t format = AST_FORMAT_SLINEAR;
-
+	struct ast_format_cap *cap = ast_format_cap_alloc_nolock();
+	struct ast_format tmp_fmt;
 	pthread_t th;
+
+	if (!cap) {
+		astman_send_error(s, m, "Internal Error. Memory allocation failure.");
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmp_fmt, AST_FORMAT_SLINEAR, 0));
+
 	if (ast_strlen_zero(name)) {
 		astman_send_error(s, m, "Channel not specified");
-		return 0;
+		res = 0;
+		goto fast_orig_cleanup;
 	}
 	if (!ast_strlen_zero(priority) && (sscanf(priority, "%30d", &pi) != 1)) {
 		if ((pi = ast_findlabel_extension(NULL, context, exten, priority, NULL)) < 1) {
 			astman_send_error(s, m, "Invalid priority");
-			return 0;
+			res = 0;
+			goto fast_orig_cleanup;
 		}
 	}
 	if (!ast_strlen_zero(timeout) && (sscanf(timeout, "%30d", &to) != 1)) {
 		astman_send_error(s, m, "Invalid timeout");
-		return 0;
+		res = 0;
+		goto fast_orig_cleanup;
 	}
 	ast_copy_string(tmp, name, sizeof(tmp));
 	tech = tmp;
 	data = strchr(tmp, '/');
 	if (!data) {
 		astman_send_error(s, m, "Invalid channel");
-		return 0;
+		res = 0;
+		goto fast_orig_cleanup;
 	}
 	*data++ = '\0';
 	ast_copy_string(tmp2, callerid, sizeof(tmp2));
@@ -3861,8 +3872,8 @@ static int action_originate(struct mansession *s, const struct message *m)
 		}
 	}
 	if (!ast_strlen_zero(codecs)) {
-		format = 0;
-		ast_parse_allow_disallow(NULL, &format, codecs, 1);
+		ast_format_cap_remove_all(cap);
+		ast_parse_allow_disallow(NULL, cap, codecs, 1);
 	}
 	/* Allocate requested channel variables */
 	vars = astman_get_variables(m);
@@ -3888,10 +3899,12 @@ static int action_originate(struct mansession *s, const struct message *m)
 			ast_copy_string(fast->context, context, sizeof(fast->context));
 			ast_copy_string(fast->exten, exten, sizeof(fast->exten));
 			ast_copy_string(fast->account, account, sizeof(fast->account));
-			fast->format = format;
+			fast->cap = cap;
+			cap = NULL; /* transfered originate helper the capabilities structure.  It is now responsible for freeing it. */
 			fast->timeout = to;
 			fast->priority = pi;
 			if (ast_pthread_create_detached(&th, NULL, fast_originate, fast)) {
+				ast_format_cap_destroy(fast->cap);
 				ast_free(fast);
 				res = -1;
 			} else {
@@ -3912,18 +3925,20 @@ static int action_originate(struct mansession *s, const struct message *m)
 				strstr(appdata, "EVAL")           /* NoOp(${EVAL(${some_var_containing_SHELL})}) */
 				)) {
 			astman_send_error(s, m, "Originate with certain 'Application' arguments requires the additional System privilege, which you do not have.");
-			return 0;
+			res = 0;
+			goto fast_orig_cleanup;
 		}
-		res = ast_pbx_outgoing_app(tech, format, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
+		res = ast_pbx_outgoing_app(tech, cap, data, to, app, appdata, &reason, 1, l, n, vars, account, NULL);
 	} else {
 		if (exten && context && pi) {
-			res = ast_pbx_outgoing_exten(tech, format, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
+			res = ast_pbx_outgoing_exten(tech, cap, data, to, context, exten, pi, &reason, 1, l, n, vars, account, NULL);
 		} else {
 			astman_send_error(s, m, "Originate with 'Exten' requires 'Context' and 'Priority'");
 			if (vars) {
 				ast_variables_destroy(vars);
 			}
-			return 0;
+			res = 0;
+			goto fast_orig_cleanup;
 		}
 	}
 	if (!res) {
@@ -3931,6 +3946,9 @@ static int action_originate(struct mansession *s, const struct message *m)
 	} else {
 		astman_send_error(s, m, "Originate failed");
 	}
+
+fast_orig_cleanup:
+	ast_format_cap_destroy(cap);
 	return 0;
 }
 
diff --git a/main/pbx.c b/main/pbx.c
index bceceb00f3a47c3fff2c429e5225a9dfdac872f5..1d8324e6e898be77266aa056a0c6d97a90eaeafb 100644
--- a/main/pbx.c
+++ b/main/pbx.c
@@ -8503,7 +8503,7 @@ static int ast_pbx_outgoing_cdr_failed(void)
 	return 0;  /* success */
 }
 
-int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel)
+int ast_pbx_outgoing_exten(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *context, const char *exten, int priority, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **channel)
 {
 	struct ast_channel *chan;
 	struct async_stat *as;
@@ -8520,7 +8520,7 @@ int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int ti
 		oh.vars = vars;
 		oh.parent_channel = NULL;
 
-		chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
+		chan = __ast_request_and_dial(type, cap, NULL, data, timeout, reason, cid_num, cid_name, &oh);
 		if (channel) {
 			*channel = chan;
 			if (chan)
@@ -8610,7 +8610,7 @@ int ast_pbx_outgoing_exten(const char *type, format_t format, void *data, int ti
 			res = -1;
 			goto outgoing_exten_cleanup;
 		}
-		chan = ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name);
+		chan = ast_request_and_dial(type, cap, NULL, data, timeout, reason, cid_num, cid_name);
 		if (channel) {
 			*channel = chan;
 			if (chan)
@@ -8669,7 +8669,7 @@ static void *ast_pbx_run_app(void *data)
 	return NULL;
 }
 
-int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
+int ast_pbx_outgoing_app(const char *type, struct ast_format_cap *cap, void *data, int timeout, const char *app, const char *appdata, int *reason, int synchronous, const char *cid_num, const char *cid_name, struct ast_variable *vars, const char *account, struct ast_channel **locked_channel)
 {
 	struct ast_channel *chan;
 	struct app_tmp *tmp;
@@ -8687,7 +8687,7 @@ int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int time
 		goto outgoing_app_cleanup;
 	}
 	if (synchronous) {
-		chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
+		chan = __ast_request_and_dial(type, cap, NULL, data, timeout, reason, cid_num, cid_name, &oh);
 		if (chan) {
 			ast_set_variables(chan, vars);
 			if (account)
@@ -8752,7 +8752,7 @@ int ast_pbx_outgoing_app(const char *type, format_t format, void *data, int time
 			res = -1;
 			goto outgoing_app_cleanup;
 		}
-		chan = __ast_request_and_dial(type, format, NULL, data, timeout, reason, cid_num, cid_name, &oh);
+		chan = __ast_request_and_dial(type, cap, NULL, data, timeout, reason, cid_num, cid_name, &oh);
 		if (!chan) {
 			ast_free(as);
 			res = -1;
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 4a4dbf5955103b7876d3bbc90f449b2611154eb6..738b58faeb978fc5c223024e353e981303c804e4 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -89,43 +89,43 @@ static const struct ast_rtp_mime_type {
 	char *subtype;
 	unsigned int sample_rate;
 } ast_rtp_mime_types[] = {
-	{{1, AST_FORMAT_G723_1}, "audio", "G723", 8000},
-	{{1, AST_FORMAT_GSM}, "audio", "GSM", 8000},
-	{{1, AST_FORMAT_ULAW}, "audio", "PCMU", 8000},
-	{{1, AST_FORMAT_ULAW}, "audio", "G711U", 8000},
-	{{1, AST_FORMAT_ALAW}, "audio", "PCMA", 8000},
-	{{1, AST_FORMAT_ALAW}, "audio", "G711A", 8000},
-	{{1, AST_FORMAT_G726}, "audio", "G726-32", 8000},
-	{{1, AST_FORMAT_ADPCM}, "audio", "DVI4", 8000},
-	{{1, AST_FORMAT_SLINEAR}, "audio", "L16", 8000},
-	{{1, AST_FORMAT_SLINEAR16}, "audio", "L16", 16000},
-	{{1, AST_FORMAT_LPC10}, "audio", "LPC", 8000},
-	{{1, AST_FORMAT_G729A}, "audio", "G729", 8000},
-	{{1, AST_FORMAT_G729A}, "audio", "G729A", 8000},
-	{{1, AST_FORMAT_G729A}, "audio", "G.729", 8000},
-	{{1, AST_FORMAT_SPEEX}, "audio", "speex", 8000},
-	{{1, AST_FORMAT_SPEEX16}, "audio", "speex", 16000},
-	{{1, AST_FORMAT_ILBC}, "audio", "iLBC", 8000},
+	{{1, {.id = AST_FORMAT_G723_1}, 0}, "audio", "G723", 8000},
+	{{1, {.id = AST_FORMAT_GSM}, 0}, "audio", "GSM", 8000},
+	{{1, {.id = AST_FORMAT_ULAW}, 0}, "audio", "PCMU", 8000},
+	{{1, {.id = AST_FORMAT_ULAW}, 0}, "audio", "G711U", 8000},
+	{{1, {.id = AST_FORMAT_ALAW}, 0}, "audio", "PCMA", 8000},
+	{{1, {.id = AST_FORMAT_ALAW}, 0}, "audio", "G711A", 8000},
+	{{1, {.id = AST_FORMAT_G726}, 0}, "audio", "G726-32", 8000},
+	{{1, {.id = AST_FORMAT_ADPCM}, 0}, "audio", "DVI4", 8000},
+	{{1, {.id = AST_FORMAT_SLINEAR}, 0}, "audio", "L16", 8000},
+	{{1, {.id = AST_FORMAT_SLINEAR16}, 0}, "audio", "L16", 16000},
+	{{1, {.id = AST_FORMAT_LPC10}, 0}, "audio", "LPC", 8000},
+	{{1, {.id = AST_FORMAT_G729A}, 0}, "audio", "G729", 8000},
+	{{1, {.id = AST_FORMAT_G729A}, 0}, "audio", "G729A", 8000},
+	{{1, {.id = AST_FORMAT_G729A}, 0}, "audio", "G.729", 8000},
+	{{1, {.id = AST_FORMAT_SPEEX}, 0}, "audio", "speex", 8000},
+	{{1, {.id = AST_FORMAT_SPEEX16}, 0},  "audio", "speex", 16000},
+	{{1, {.id = AST_FORMAT_ILBC}, 0}, "audio", "iLBC", 8000},
 	/* this is the sample rate listed in the RTP profile for the G.722
 	              codec, *NOT* the actual sample rate of the media stream
 	*/
-	{{1, AST_FORMAT_G722}, "audio", "G722", 8000},
-	{{1, AST_FORMAT_G726_AAL2}, "audio", "AAL2-G726-32", 8000},
-	{{0, AST_RTP_DTMF}, "audio", "telephone-event", 8000},
-	{{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event", 8000},
-	{{0, AST_RTP_CN}, "audio", "CN", 8000},
-	{{1, AST_FORMAT_JPEG}, "video", "JPEG", 90000},
-	{{1, AST_FORMAT_PNG}, "video", "PNG", 90000},
-	{{1, AST_FORMAT_H261}, "video", "H261", 90000},
-	{{1, AST_FORMAT_H263}, "video", "H263", 90000},
-	{{1, AST_FORMAT_H263_PLUS}, "video", "h263-1998", 90000},
-	{{1, AST_FORMAT_H264}, "video", "H264", 90000},
-	{{1, AST_FORMAT_MP4_VIDEO}, "video", "MP4V-ES", 90000},
-	{{1, AST_FORMAT_T140RED}, "text", "RED", 1000},
-	{{1, AST_FORMAT_T140}, "text", "T140", 1000},
-	{{1, AST_FORMAT_SIREN7}, "audio", "G7221", 16000},
-	{{1, AST_FORMAT_SIREN14}, "audio", "G7221", 32000},
-	{{1, AST_FORMAT_G719}, "audio", "G719", 48000},
+	{{1, {.id = AST_FORMAT_G722}, 0}, "audio", "G722", 8000},
+	{{1, {.id = AST_FORMAT_G726_AAL2}, 0}, "audio", "AAL2-G726-32", 8000},
+	{{0, {.id = 0}, AST_RTP_DTMF}, "audio", "telephone-event", 8000},
+	{{0, {.id = 0}, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event", 8000},
+	{{0, {.id = 0}, AST_RTP_CN}, "audio", "CN", 8000},
+	{{1, {.id = AST_FORMAT_JPEG}, 0}, "video", "JPEG", 90000},
+	{{1, {.id = AST_FORMAT_PNG}, 0}, "video", "PNG", 90000},
+	{{1, {.id = AST_FORMAT_H261}, 0}, "video", "H261", 90000},
+	{{1, {.id = AST_FORMAT_H263}, 0}, "video", "H263", 90000},
+	{{1, {.id = AST_FORMAT_H263_PLUS}, 0}, "video", "h263-1998", 90000},
+	{{1, {.id = AST_FORMAT_H264}, 0}, "video", "H264", 90000},
+	{{1, {.id = AST_FORMAT_MP4_VIDEO}, 0}, "video", "MP4V-ES", 90000},
+	{{1, {.id = AST_FORMAT_T140RED}, 0}, "text", "RED", 1000},
+	{{1, {.id = AST_FORMAT_T140}, 0}, "text", "T140", 1000},
+	{{1, {.id = AST_FORMAT_SIREN7}, 0}, "audio", "G7221", 16000},
+	{{1, {.id = AST_FORMAT_SIREN14}, 0}, "audio", "G7221", 32000},
+	{{1, {.id = AST_FORMAT_G719}, 0}, "audio", "G719", 48000},
 };
 
 /*!
@@ -139,44 +139,44 @@ static const struct ast_rtp_mime_type {
  * assigned values
  */
 static const struct ast_rtp_payload_type static_RTP_PT[AST_RTP_MAX_PT] = {
-	[0] = {1, AST_FORMAT_ULAW},
+	[0] = {1, {.id = AST_FORMAT_ULAW}, 0},
 	#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, {.id = AST_FORMAT_G726}, 0},/* 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_SIREN7},
-	[103] = {1, AST_FORMAT_H263_PLUS},
-	[104] = {1, AST_FORMAT_MP4_VIDEO},
-	[105] = {1, AST_FORMAT_T140RED},   /* Real time text chat (with redundancy encoding) */
-	[106] = {1, AST_FORMAT_T140},      /* Real time text chat */
-	[110] = {1, AST_FORMAT_SPEEX},
-	[111] = {1, AST_FORMAT_G726},
-	[112] = {1, AST_FORMAT_G726_AAL2},
-	[115] = {1, AST_FORMAT_SIREN14},
-	[116] = {1, AST_FORMAT_G719},
-	[117] = {1, AST_FORMAT_SPEEX16},
-	[118] = {1, AST_FORMAT_SLINEAR16}, /* 16 Khz signed linear */
-	[121] = {0, AST_RTP_CISCO_DTMF},   /* Must be type 121 */
+	[3] = {1, {.id = AST_FORMAT_GSM}, 0},
+	[4] = {1, {.id = AST_FORMAT_G723_1}, 0},
+	[5] = {1, {.id = AST_FORMAT_ADPCM}, 0},/* 8 kHz */
+	[6] = {1, {.id = AST_FORMAT_ADPCM}, 0}, /* 16 kHz */
+	[7] = {1, {.id = AST_FORMAT_LPC10}, 0},
+	[8] = {1, {.id = AST_FORMAT_ALAW}, 0},
+	[9] = {1, {.id = AST_FORMAT_G722}, 0},
+	[10] = {1, {.id = AST_FORMAT_SLINEAR}, 0}, /* 2 channels */
+	[11] = {1, {.id = AST_FORMAT_SLINEAR}, 0}, /* 1 channel */
+	[13] = {0, {.id = 0}, AST_RTP_CN},
+	[16] = {1, {.id = AST_FORMAT_ADPCM}, 0}, /* 11.025 kHz */
+	[17] = {1, {.id = AST_FORMAT_ADPCM}, 0}, /* 22.050 kHz */
+	[18] = {1, {.id = AST_FORMAT_G729A}, 0},
+	[19] = {0, {.id = 0}, AST_RTP_CN},         /* Also used for CN */
+	[26] = {1, {.id = AST_FORMAT_JPEG}, 0},
+	[31] = {1, {.id = AST_FORMAT_H261}, 0},
+	[34] = {1, {.id = AST_FORMAT_H263}, 0},
+	[97] = {1, {.id = AST_FORMAT_ILBC}, 0},
+	[98] = {1, {.id = AST_FORMAT_H263_PLUS}, 0},
+	[99] = {1, {.id = AST_FORMAT_H264}, 0},
+	[101] = {0, {.id = 0}, AST_RTP_DTMF},
+	[102] = {1, {.id = AST_FORMAT_SIREN7}, 0},
+	[103] = {1, {.id = AST_FORMAT_H263_PLUS}, 0},
+	[104] = {1, {.id = AST_FORMAT_MP4_VIDEO}, 0},
+	[105] = {1, {.id = AST_FORMAT_T140RED}, 0},   /* Real time text chat (with redundancy encoding) */
+	[106] = {1, {.id = AST_FORMAT_T140}, 0},      /* Real time text chat */
+	[110] = {1, {.id = AST_FORMAT_SPEEX}, 0},
+	[111] = {1, {.id = AST_FORMAT_G726}, 0},
+	[112] = {1, {.id = AST_FORMAT_G726_AAL2}, 0},
+	[115] = {1, {.id = AST_FORMAT_SIREN14}, 0},
+	[116] = {1, {.id = AST_FORMAT_G719}, 0},
+	[117] = {1, {.id = AST_FORMAT_SPEEX16}, 0},
+	[118] = {1, {.id = AST_FORMAT_SLINEAR16}, 0}, /* 16 Khz signed linear */
+	[121] = {0, {.id = 0}, AST_RTP_CISCO_DTMF},   /* Must be type 121 */
 };
 
 int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)
@@ -485,9 +485,10 @@ void ast_rtp_codecs_payloads_clear(struct ast_rtp_codecs *codecs, struct ast_rtp
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
 		codecs->payloads[i].asterisk_format = 0;
-		codecs->payloads[i].code = 0;
+		codecs->payloads[i].rtp_code = 0;
+		ast_format_clear(&codecs->payloads[i].format);
 		if (instance && instance->engine && instance->engine->payload_set) {
-			instance->engine->payload_set(instance, i, 0, 0);
+			instance->engine->payload_set(instance, i, 0, NULL, 0);
 		}
 	}
 }
@@ -497,11 +498,13 @@ void ast_rtp_codecs_payloads_default(struct ast_rtp_codecs *codecs, struct ast_r
 	int i;
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
-		if (static_RTP_PT[i].code) {
+		if (static_RTP_PT[i].rtp_code || static_RTP_PT[i].asterisk_format) {
+
 			codecs->payloads[i].asterisk_format = static_RTP_PT[i].asterisk_format;
-			codecs->payloads[i].code = static_RTP_PT[i].code;
+			codecs->payloads[i].rtp_code = static_RTP_PT[i].rtp_code;
+			ast_format_copy(&codecs->payloads[i].format, &static_RTP_PT[i].format);
 			if (instance && instance->engine && instance->engine->payload_set) {
-				instance->engine->payload_set(instance, i, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
+				instance->engine->payload_set(instance, i, codecs->payloads[i].asterisk_format, &codecs->payloads[i].format, codecs->payloads[i].rtp_code);
 			}
 		}
 	}
@@ -512,12 +515,13 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod
 	int i;
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
-		if (src->payloads[i].code) {
+		if (src->payloads[i].rtp_code || src->payloads[i].asterisk_format) {
 			ast_debug(2, "Copying payload %d from %p to %p\n", i, src, dest);
 			dest->payloads[i].asterisk_format = src->payloads[i].asterisk_format;
-			dest->payloads[i].code = src->payloads[i].code;
+			dest->payloads[i].rtp_code = src->payloads[i].rtp_code;
+			ast_format_copy(&dest->payloads[i].format, &src->payloads[i].format);
 			if (instance && instance->engine && instance->engine->payload_set) {
-				instance->engine->payload_set(instance, i, dest->payloads[i].asterisk_format, dest->payloads[i].code);
+				instance->engine->payload_set(instance, i, dest->payloads[i].asterisk_format, &dest->payloads[i].format, dest->payloads[i].rtp_code);
 			}
 		}
 	}
@@ -525,17 +529,18 @@ void ast_rtp_codecs_payloads_copy(struct ast_rtp_codecs *src, struct ast_rtp_cod
 
 void ast_rtp_codecs_payloads_set_m_type(struct ast_rtp_codecs *codecs, struct ast_rtp_instance *instance, int payload)
 {
-	if (payload < 0 || payload >= AST_RTP_MAX_PT || !static_RTP_PT[payload].code) {
+	if (payload < 0 || payload >= AST_RTP_MAX_PT || (!static_RTP_PT[payload].rtp_code && !static_RTP_PT[payload].asterisk_format)) {
 		return;
 	}
 
 	codecs->payloads[payload].asterisk_format = static_RTP_PT[payload].asterisk_format;
-	codecs->payloads[payload].code = static_RTP_PT[payload].code;
+	codecs->payloads[payload].rtp_code = static_RTP_PT[payload].rtp_code;
+	ast_format_copy(&codecs->payloads[payload].format, &static_RTP_PT[payload].format);
 
 	ast_debug(1, "Setting payload %d based on m type on %p\n", payload, codecs);
 
 	if (instance && instance->engine && instance->engine->payload_set) {
-		instance->engine->payload_set(instance, payload, codecs->payloads[payload].asterisk_format, codecs->payloads[payload].code);
+		instance->engine->payload_set(instance, payload, codecs->payloads[payload].asterisk_format, &codecs->payloads[payload].format, codecs->payloads[payload].rtp_code);
 	}
 }
 
@@ -572,14 +577,12 @@ int ast_rtp_codecs_payloads_set_rtpmap_type_rate(struct ast_rtp_codecs *codecs,
 		found = 1;
 		codecs->payloads[pt] = t->payload_type;
 
-		if ((t->payload_type.code == AST_FORMAT_G726) &&
-		                        t->payload_type.asterisk_format &&
-		    (options & AST_RTP_OPT_G726_NONSTANDARD)) {
-			codecs->payloads[pt].code = AST_FORMAT_G726_AAL2;
+		if ((t->payload_type.format.id == AST_FORMAT_G726) && t->payload_type.asterisk_format && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+			ast_format_set(&codecs->payloads[pt].format, AST_FORMAT_G726_AAL2, 0);
 		}
 
 		if (instance && instance->engine && instance->engine->payload_set) {
-			instance->engine->payload_set(instance, pt, codecs->payloads[i].asterisk_format, codecs->payloads[i].code);
+			instance->engine->payload_set(instance, pt, codecs->payloads[i].asterisk_format, &codecs->payloads[i].format, codecs->payloads[i].rtp_code);
 		}
 
 		break;
@@ -602,10 +605,11 @@ void ast_rtp_codecs_payloads_unset(struct ast_rtp_codecs *codecs, struct ast_rtp
 	ast_debug(2, "Unsetting payload %d on %p\n", payload, codecs);
 
 	codecs->payloads[payload].asterisk_format = 0;
-	codecs->payloads[payload].code = 0;
+	codecs->payloads[payload].rtp_code = 0;
+	ast_format_clear(&codecs->payloads[payload].format);
 
 	if (instance && instance->engine && instance->engine->payload_set) {
-		instance->engine->payload_set(instance, payload, 0, 0);
+		instance->engine->payload_set(instance, payload, 0, NULL, 0);
 	}
 }
 
@@ -618,45 +622,55 @@ struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs
 	}
 
 	result.asterisk_format = codecs->payloads[payload].asterisk_format;
-	result.code = codecs->payloads[payload].code;
+	result.rtp_code = codecs->payloads[payload].rtp_code;
+	ast_format_copy(&result.format, &codecs->payloads[payload].format);
 
-	if (!result.code) {
+	if (!result.rtp_code && !result.asterisk_format) {
 		result = static_RTP_PT[payload];
 	}
 
 	return result;
 }
 
-void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, format_t *astformats, int *nonastformats)
+void ast_rtp_codecs_payload_formats(struct ast_rtp_codecs *codecs, struct ast_format_cap *astformats, int *nonastformats)
 {
 	int i;
 
-	*astformats = *nonastformats = 0;
+	ast_format_cap_remove_all(astformats);
+	*nonastformats = 0;
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
-		if (codecs->payloads[i].code) {
+		if (codecs->payloads[i].rtp_code || codecs->payloads[i].asterisk_format) {
 			ast_debug(1, "Incorporating payload %d on %p\n", i, codecs);
 		}
 		if (codecs->payloads[i].asterisk_format) {
-			*astformats |= codecs->payloads[i].code;
+			ast_format_cap_add(astformats, &codecs->payloads[i].format);
 		} else {
-			*nonastformats |= codecs->payloads[i].code;
+			*nonastformats |= codecs->payloads[i].rtp_code;
 		}
 	}
 }
 
-int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
+int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
 {
 	int i;
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
-		if (codecs->payloads[i].asterisk_format == asterisk_format && codecs->payloads[i].code == code) {
+		if (codecs->payloads[i].asterisk_format && asterisk_format && format &&
+			(ast_format_cmp(format, &codecs->payloads[i].format) != AST_FORMAT_CMP_NOT_EQUAL)) {
+			return i;
+		} else if (!codecs->payloads[i].asterisk_format && !asterisk_format &&
+			(codecs->payloads[i].rtp_code == code)) {
 			return i;
 		}
 	}
 
 	for (i = 0; i < AST_RTP_MAX_PT; i++) {
-		if (static_RTP_PT[i].asterisk_format == asterisk_format && static_RTP_PT[i].code == code) {
+		if (static_RTP_PT[i].asterisk_format && asterisk_format && format &&
+			(ast_format_cmp(format, &static_RTP_PT[i].format) != AST_FORMAT_CMP_NOT_EQUAL)) {
+			return i;
+		} else if (!static_RTP_PT[i].asterisk_format && !asterisk_format &&
+			(static_RTP_PT[i].rtp_code == code)) {
 			return i;
 		}
 	}
@@ -664,29 +678,38 @@ int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asteris
 	return -1;
 }
 
-const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, const format_t code, enum ast_rtp_options options)
+const char *ast_rtp_lookup_mime_subtype2(const int asterisk_format, struct ast_format *format, int code, enum ast_rtp_options options)
 {
 	int i;
 
 	for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); i++) {
-		if (ast_rtp_mime_types[i].payload_type.code == code && ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format) {
-			if (asterisk_format && (code == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
+		if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
+			(ast_format_cmp(format, &ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
+			if ((format->id == AST_FORMAT_G726_AAL2) && (options & AST_RTP_OPT_G726_NONSTANDARD)) {
 				return "G726-32";
 			} else {
 				return ast_rtp_mime_types[i].subtype;
 			}
+		} else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
+			ast_rtp_mime_types[i].payload_type.rtp_code == code) {
+
+			return ast_rtp_mime_types[i].subtype;
 		}
 	}
 
 	return "";
 }
 
-unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code)
+unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, struct ast_format *format, int code)
 {
 	unsigned int i;
 
 	for (i = 0; i < ARRAY_LEN(ast_rtp_mime_types); ++i) {
-		if ((ast_rtp_mime_types[i].payload_type.code == code) && (ast_rtp_mime_types[i].payload_type.asterisk_format == asterisk_format)) {
+		if (ast_rtp_mime_types[i].payload_type.asterisk_format && asterisk_format && format &&
+			(ast_format_cmp(format, &ast_rtp_mime_types[i].payload_type.format) != AST_FORMAT_CMP_NOT_EQUAL)) {
+			return ast_rtp_mime_types[i].sample_rate;
+		} else if (!ast_rtp_mime_types[i].payload_type.asterisk_format && !asterisk_format &&
+			ast_rtp_mime_types[i].payload_type.rtp_code == code) {
 			return ast_rtp_mime_types[i].sample_rate;
 		}
 	}
@@ -694,23 +717,35 @@ unsigned int ast_rtp_lookup_sample_rate2(int asterisk_format, format_t code)
 	return 0;
 }
 
-char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, const format_t capability, const int asterisk_format, enum ast_rtp_options options)
+char *ast_rtp_lookup_mime_multiple2(struct ast_str *buf, struct ast_format_cap *ast_format_capability, int rtp_capability, const int asterisk_format, enum ast_rtp_options options)
 {
-	format_t format;
 	int found = 0;
-
+	const char *name;
 	if (!buf) {
 		return NULL;
 	}
 
-	ast_str_append(&buf, 0, "0x%llx (", (unsigned long long) capability);
 
-	for (format = 1; format < AST_RTP_MAX; format <<= 1) {
-		if (capability & format) {
-			const char *name = ast_rtp_lookup_mime_subtype2(asterisk_format, format, options);
+	if (asterisk_format) {
+		struct ast_format tmp_fmt;
+		ast_format_cap_iter_start(ast_format_capability);
+		while (!ast_format_cap_iter_next(ast_format_capability, &tmp_fmt)) {
+			name = ast_rtp_lookup_mime_subtype2(asterisk_format, &tmp_fmt, 0, options);
 			ast_str_append(&buf, 0, "%s|", name);
 			found = 1;
 		}
+		ast_format_cap_iter_end(ast_format_capability);
+
+	} else {
+		int x;
+		ast_str_append(&buf, 0, "0x%x (", (unsigned int) rtp_capability);
+		for (x = 1; x < AST_RTP_MAX; x <<= 1) {
+			if (rtp_capability & x) {
+				name = ast_rtp_lookup_mime_subtype2(asterisk_format, NULL, x, options);
+				ast_str_append(&buf, 0, "%s|", name);
+				found = 1;
+			}
+		}
 	}
 
 	ast_str_append(&buf, 0, "%s", found ? ")" : "nothing)");
@@ -842,7 +877,8 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
 	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 ((ast_format_cmp(&c0->rawreadformat, &c1->rawwriteformat) == AST_FORMAT_CMP_NOT_EQUAL) ||
+			(ast_format_cmp(&c1->rawreadformat, &c0->rawwriteformat) == AST_FORMAT_CMP_NOT_EQUAL)) {
 			ast_debug(1, "rtp-engine-local-bridge: Oooh, formats changed, backing out\n");
 			res = AST_BRIDGE_FAILED_NOWARN;
 			break;
@@ -969,20 +1005,40 @@ static enum ast_bridge_result local_bridge_loop(struct ast_channel *c0, struct a
 	return res;
 }
 
-static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1,
-						 struct ast_rtp_instance *vinstance0, struct ast_rtp_instance *vinstance1, struct ast_rtp_instance *tinstance0,
-						 struct ast_rtp_instance *tinstance1, struct ast_rtp_glue *glue0, struct ast_rtp_glue *glue1, format_t codec0, format_t codec1, int timeoutms,
-						 int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1)
+static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0,
+	struct ast_channel *c1,
+	struct ast_rtp_instance *instance0,
+	struct ast_rtp_instance *instance1,
+	struct ast_rtp_instance *vinstance0,
+	struct ast_rtp_instance *vinstance1,
+	struct ast_rtp_instance *tinstance0,
+	struct ast_rtp_instance *tinstance1,
+	struct ast_rtp_glue *glue0,
+	struct ast_rtp_glue *glue1,
+	struct ast_format_cap *cap0,
+	struct ast_format_cap *cap1,
+	int timeoutms,
+	int flags,
+	struct ast_frame **fo,
+	struct ast_channel **rc,
+	void *pvt0,
+	void *pvt1)
 {
 	enum ast_bridge_result res = AST_BRIDGE_FAILED;
 	struct ast_channel *who = NULL, *other = NULL, *cs[3] = { NULL, };
-	format_t oldcodec0 = codec0, oldcodec1 = codec1;
+	struct ast_format_cap *oldcap0 = ast_format_cap_dup(cap0);
+	struct ast_format_cap *oldcap1 = ast_format_cap_dup(cap1);
 	struct ast_sockaddr ac1 = {{0,}}, vac1 = {{0,}}, tac1 = {{0,}}, ac0 = {{0,}}, vac0 = {{0,}}, tac0 = {{0,}};
 	struct ast_sockaddr t1 = {{0,}}, vt1 = {{0,}}, tt1 = {{0,}}, t0 = {{0,}}, vt0 = {{0,}}, tt0 = {{0,}};
 	struct ast_frame *fr = NULL;
 
+	if (!oldcap0 || !oldcap1) {
+		ast_channel_unlock(c0);
+		ast_channel_unlock(c1);
+		goto remote_bridge_cleanup;
+	}
 	/* Test the first channel */
-	if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0))) {
+	if (!(glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0))) {
 		ast_rtp_instance_get_remote_address(instance1, &ac1);
 		if (vinstance1) {
 			ast_rtp_instance_get_remote_address(vinstance1, &vac1);
@@ -995,7 +1051,7 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 	}
 
 	/* Test the second channel */
-	if (!(glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0))) {
+	if (!(glue1->update_peer(c1, instance0, vinstance0, tinstance0, cap0, 0))) {
 		ast_rtp_instance_get_remote_address(instance0, &ac0);
 		if (vinstance0) {
 			ast_rtp_instance_get_remote_address(instance0, &vac0);
@@ -1039,7 +1095,8 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 			ast_rtp_instance_get_remote_address(tinstance1, &tt1);
 		}
 		if (glue1->get_codec) {
-			codec1 = glue1->get_codec(c1);
+			ast_format_cap_remove_all(cap1);
+			glue1->get_codec(c1, cap1);
 		}
 
 		ast_rtp_instance_get_remote_address(instance0, &t0);
@@ -1050,63 +1107,66 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 			ast_rtp_instance_get_remote_address(tinstance0, &tt0);
 		}
 		if (glue0->get_codec) {
-			codec0 = glue0->get_codec(c0);
+			ast_format_cap_remove_all(cap0);
+			glue0->get_codec(c0, cap0);
 		}
 
 		if ((ast_sockaddr_cmp(&t1, &ac1)) ||
 		    (vinstance1 && ast_sockaddr_cmp(&vt1, &vac1)) ||
 		    (tinstance1 && ast_sockaddr_cmp(&tt1, &tac1)) ||
-		    (codec1 != oldcodec1)) {
+		    (!ast_format_cap_identical(cap1, oldcap1))) {
+			char tmp_buf[512] = { 0, };
 			ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&t1),
-				  ast_getformatname(codec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
 			ast_debug(1, "Oooh, '%s' changed end vaddress to %s (format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&vt1),
-				  ast_getformatname(codec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
 			ast_debug(1, "Oooh, '%s' changed end taddress to %s (format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&tt1),
-				  ast_getformatname(codec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap1));
 			ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&ac1),
-				  ast_getformatname(oldcodec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
 			ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&vac1),
-				  ast_getformatname(oldcodec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
 			ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
 				  c1->name, ast_sockaddr_stringify(&tac1),
-				  ast_getformatname(oldcodec1));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap1));
 			if (glue0->update_peer(c0,
 					       ast_sockaddr_isnull(&t1)  ? NULL : instance1,
 					       ast_sockaddr_isnull(&vt1) ? NULL : vinstance1,
 					       ast_sockaddr_isnull(&tt1) ? NULL : tinstance1,
-					       codec1, 0)) {
+					       cap1, 0)) {
 				ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
 			}
 			ast_sockaddr_copy(&ac1, &t1);
 			ast_sockaddr_copy(&vac1, &vt1);
 			ast_sockaddr_copy(&tac1, &tt1);
-			oldcodec1 = codec1;
+			ast_format_cap_copy(oldcap1, cap1);
 		}
 		if ((ast_sockaddr_cmp(&t0, &ac0)) ||
 		    (vinstance0 && ast_sockaddr_cmp(&vt0, &vac0)) ||
 		    (tinstance0 && ast_sockaddr_cmp(&tt0, &tac0)) ||
-		    (codec0 != oldcodec0)) {
+		    (!ast_format_cap_identical(cap0, oldcap0))) {
+			char tmp_buf[512] = { 0, };
 			ast_debug(1, "Oooh, '%s' changed end address to %s (format %s)\n",
 				  c0->name, ast_sockaddr_stringify(&t0),
-				  ast_getformatname(codec0));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), cap0));
 			ast_debug(1, "Oooh, '%s' was %s/(format %s)\n",
 				  c0->name, ast_sockaddr_stringify(&ac0),
-				  ast_getformatname(oldcodec0));
+				  ast_getformatname_multiple(tmp_buf, sizeof(tmp_buf), oldcap0));
 			if (glue1->update_peer(c1, t0.len ? instance0 : NULL,
 						vt0.len ? vinstance0 : NULL,
 						tt0.len ? tinstance0 : NULL,
-						codec0, 0)) {
+						cap0, 0)) {
 				ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
 			}
 			ast_sockaddr_copy(&ac0, &t0);
 			ast_sockaddr_copy(&vac0, &vt0);
 			ast_sockaddr_copy(&tac0, &tt0);
-			oldcodec0 = codec0;
+			ast_format_cap_copy(oldcap0, cap0);
 		}
 
 		/* Wait for frame to come in on the channels */
@@ -1148,9 +1208,9 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 				} else if (fr->subclass.integer == AST_CONTROL_UNHOLD) {
 					/* If they went off hold they should go back to being direct */
 					if (who == c0) {
-						glue1->update_peer(c1, instance0, vinstance0, tinstance0, codec0, 0);
+						glue1->update_peer(c1, instance0, vinstance0, tinstance0, cap0, 0);
 					} else {
-						glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0);
+						glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0);
 					}
 				}
 				/* Update local address information */
@@ -1160,10 +1220,17 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 				ast_sockaddr_copy(&ac1, &t1);
 				/* Update codec information */
 				if (glue0->get_codec && c0->tech_pvt) {
-					oldcodec0 = codec0 = glue0->get_codec(c0);
+					ast_format_cap_remove_all(cap0);
+					ast_format_cap_remove_all(oldcap0);
+					glue0->get_codec(c0, cap0);
+					ast_format_cap_append(oldcap0, cap0);
+
 				}
 				if (glue1->get_codec && c1->tech_pvt) {
-					oldcodec1 = codec1 = glue1->get_codec(c1);
+					ast_format_cap_remove_all(cap1);
+					ast_format_cap_remove_all(oldcap1);
+					glue0->get_codec(c1, cap1);
+					ast_format_cap_append(oldcap1, cap1);
 				}
 				ast_indicate_data(other, fr->subclass.integer, fr->data.ptr, fr->datalen);
 				ast_frfree(fr);
@@ -1181,7 +1248,8 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 				*fo = fr;
 				*rc = who;
 				ast_debug(1, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass.integer, who->name);
-				return AST_BRIDGE_COMPLETE;
+				res = AST_BRIDGE_COMPLETE;
+				goto remote_bridge_cleanup;
 			}
 		} else {
 			if ((fr->frametype == AST_FRAME_DTMF_BEGIN) ||
@@ -1214,6 +1282,10 @@ static enum ast_bridge_result remote_bridge_loop(struct ast_channel *c0, struct
 
 	ast_poll_channel_del(c0, c1);
 
+remote_bridge_cleanup:
+	ast_format_cap_destroy(oldcap0);
+	ast_format_cap_destroy(oldcap1);
+
 	return res;
 }
 
@@ -1238,9 +1310,15 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as
 	enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
 	enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
 	enum ast_bridge_result res = AST_BRIDGE_FAILED;
-	format_t codec0 = 0, codec1 = 0;
+	struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock();
 	int unlock_chans = 1;
 
+	if (!cap0 || !cap1) {
+		unlock_chans = 0;
+		goto done;
+	}
+
 	/* Lock both channels so we can look for the glue that binds them together */
 	ast_channel_lock(c0);
 	while (ast_channel_trylock(c1)) {
@@ -1311,10 +1389,18 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as
 	}
 
 	/* Make sure that codecs match */
-	codec0 = glue0->get_codec ? glue0->get_codec(c0) : 0;
-	codec1 = glue1->get_codec ? glue1->get_codec(c1) : 0;
-	if (codec0 && codec1 && !(codec0 & codec1)) {
-		ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n", ast_getformatname(codec0), ast_getformatname(codec1));
+	if (glue0->get_codec){
+		glue0->get_codec(c0, cap0);
+	}
+	if (glue1->get_codec) {
+		glue1->get_codec(c1, cap1);
+	}
+	if (!ast_format_cap_is_empty(cap0) && !ast_format_cap_is_empty(cap1) && !ast_format_cap_has_joint(cap0, cap1)) {
+		char tmp0[256] = { 0, };
+		char tmp1[256] = { 0, };
+		ast_debug(1, "Channel codec0 = %s is not codec1 = %s, cannot native bridge in RTP.\n",
+			ast_getformatname_multiple(tmp0, sizeof(tmp0), cap0),
+			ast_getformatname_multiple(tmp1, sizeof(tmp1), cap1));
 		res = AST_BRIDGE_FAILED_NOWARN;
 		goto done;
 	}
@@ -1331,7 +1417,7 @@ enum ast_bridge_result ast_rtp_instance_bridge(struct ast_channel *c0, struct as
 	} else {
 		ast_verbose(VERBOSE_PREFIX_3 "Remotely bridging %s and %s\n", c0->name, c1->name);
 		res = remote_bridge_loop(c0, c1, instance0, instance1, vinstance0, vinstance1,
-				tinstance0, tinstance1, glue0, glue1, codec0, codec1, timeoutms, flags,
+				tinstance0, tinstance1, glue0, glue1, cap0, cap1, timeoutms, flags,
 				fo, rc, c0->tech_pvt, c1->tech_pvt);
 	}
 
@@ -1347,6 +1433,8 @@ done:
 		ast_channel_unlock(c0);
 		ast_channel_unlock(c1);
 	}
+	ast_format_cap_destroy(cap1);
+	ast_format_cap_destroy(cap0);
 
 	unref_instance_cond(&instance0);
 	unref_instance_cond(&instance1);
@@ -1371,7 +1459,8 @@ void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struc
 	struct ast_rtp_glue *glue0, *glue1;
 	enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
 	enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
-	format_t codec0 = 0, codec1 = 0;
+	struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock();
 	int res = 0;
 
 	/* Lock both channels so we can look for the glue that binds them together */
@@ -1382,6 +1471,10 @@ void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struc
 		ast_channel_lock(c0);
 	}
 
+	if (!cap1 || !cap0) {
+		goto done;
+	}
+
 	/* Grab glue that binds each channel to something using the RTP engine */
 	if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
 		ast_debug(1, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
@@ -1404,10 +1497,10 @@ void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struc
 		audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
 	}
 	if (audio_glue0_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue0_res == AST_RTP_GLUE_RESULT_FORBID || video_glue0_res == AST_RTP_GLUE_RESULT_REMOTE) && glue0->get_codec) {
-		codec0 = glue0->get_codec(c0);
+		glue0->get_codec(c0, cap0);
 	}
 	if (audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue1_res == AST_RTP_GLUE_RESULT_FORBID || video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) && glue1->get_codec) {
-		codec1 = glue1->get_codec(c1);
+		glue1->get_codec(c1, cap1);
 	}
 
 	/* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
@@ -1416,7 +1509,7 @@ void ast_rtp_instance_early_bridge_make_compatible(struct ast_channel *c0, struc
 	}
 
 	/* Make sure we have matching codecs */
-	if (!(codec0 & codec1)) {
+	if (!ast_format_cap_has_joint(cap0, cap1)) {
 		goto done;
 	}
 
@@ -1435,6 +1528,9 @@ done:
 	ast_channel_unlock(c0);
 	ast_channel_unlock(c1);
 
+	ast_format_cap_destroy(cap0);
+	ast_format_cap_destroy(cap1);
+
 	unref_instance_cond(&instance0);
 	unref_instance_cond(&instance1);
 	unref_instance_cond(&vinstance0);
@@ -1455,11 +1551,14 @@ int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1
 	struct ast_rtp_glue *glue0, *glue1;
 	enum ast_rtp_glue_result audio_glue0_res = AST_RTP_GLUE_RESULT_FORBID, video_glue0_res = AST_RTP_GLUE_RESULT_FORBID, text_glue0_res = AST_RTP_GLUE_RESULT_FORBID;
 	enum ast_rtp_glue_result audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID, video_glue1_res = AST_RTP_GLUE_RESULT_FORBID, text_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
-	format_t codec0 = 0, codec1 = 0;
+	struct ast_format_cap *cap0 = ast_format_cap_alloc_nolock();
+	struct ast_format_cap *cap1 = ast_format_cap_alloc_nolock();
 	int res = 0;
 
 	/* If there is no second channel just immediately bail out, we are of no use in that scenario */
 	if (!c1) {
+		ast_format_cap_destroy(cap0);
+		ast_format_cap_destroy(cap1);
 		return -1;
 	}
 
@@ -1471,6 +1570,10 @@ int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1
 		ast_channel_lock(c0);
 	}
 
+	if (!cap1 || !cap0) {
+		goto done;
+	}
+
 	/* Grab glue that binds each channel to something using the RTP engine */
 	if (!(glue0 = ast_rtp_instance_get_glue(c0->tech->type)) || !(glue1 = ast_rtp_instance_get_glue(c1->tech->type))) {
 		ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", glue0 ? c1->name : c0->name);
@@ -1492,11 +1595,11 @@ int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1
 	if (video_glue1_res != AST_RTP_GLUE_RESULT_FORBID && (audio_glue1_res != AST_RTP_GLUE_RESULT_REMOTE || video_glue1_res != AST_RTP_GLUE_RESULT_REMOTE)) {
 		audio_glue1_res = AST_RTP_GLUE_RESULT_FORBID;
 	}
-	if (audio_glue0_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue0_res == AST_RTP_GLUE_RESULT_FORBID || video_glue0_res == AST_RTP_GLUE_RESULT_REMOTE) && glue0->get_codec(c0)) {
-		codec0 = glue0->get_codec(c0);
+	if (audio_glue0_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue0_res == AST_RTP_GLUE_RESULT_FORBID || video_glue0_res == AST_RTP_GLUE_RESULT_REMOTE) && glue0->get_codec) {
+		glue0->get_codec(c0, cap0);
 	}
-	if (audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue1_res == AST_RTP_GLUE_RESULT_FORBID || video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) && glue1->get_codec(c1)) {
-		codec1 = glue1->get_codec(c1);
+	if (audio_glue1_res == AST_RTP_GLUE_RESULT_REMOTE && (video_glue1_res == AST_RTP_GLUE_RESULT_FORBID || video_glue1_res == AST_RTP_GLUE_RESULT_REMOTE) && glue1->get_codec) {
+		glue1->get_codec(c1, cap1);
 	}
 
 	/* If any sort of bridge is forbidden just completely bail out and go back to generic bridging */
@@ -1505,12 +1608,12 @@ int ast_rtp_instance_early_bridge(struct ast_channel *c0, struct ast_channel *c1
 	}
 
 	/* Make sure we have matching codecs */
-	if (!(codec0 & codec1)) {
+	if (!ast_format_cap_has_joint(cap0, cap1)) {
 		goto done;
 	}
 
 	/* Bridge media early */
-	if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, codec1, 0)) {
+	if (glue0->update_peer(c0, instance1, vinstance1, tinstance1, cap1, 0)) {
 		ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", c0->name, c1 ? c1->name : "<unspecified>");
 	}
 
@@ -1520,6 +1623,9 @@ done:
 	ast_channel_unlock(c0);
 	ast_channel_unlock(c1);
 
+	ast_format_cap_destroy(cap0);
+	ast_format_cap_destroy(cap1);
+
 	unref_instance_cond(&instance0);
 	unref_instance_cond(&instance1);
 	unref_instance_cond(&vinstance0);
@@ -1623,12 +1729,12 @@ void ast_rtp_instance_set_stats_vars(struct ast_channel *chan, struct ast_rtp_in
 	}
 }
 
-int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, format_t format)
+int ast_rtp_instance_set_read_format(struct ast_rtp_instance *instance, struct ast_format *format)
 {
 	return instance->engine->set_read_format ? instance->engine->set_read_format(instance, format) : -1;
 }
 
-int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, format_t format)
+int ast_rtp_instance_set_write_format(struct ast_rtp_instance *instance, struct ast_format *format)
 {
 	return instance->engine->set_write_format ? instance->engine->set_write_format(instance, format) : -1;
 }
@@ -1669,15 +1775,16 @@ int ast_rtp_instance_make_compatible(struct ast_channel *chan, struct ast_rtp_in
 	return res;
 }
 
-format_t ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, format_t to_endpoint, format_t to_asterisk)
+void ast_rtp_instance_available_formats(struct ast_rtp_instance *instance, struct ast_format_cap *to_endpoint, struct ast_format_cap *to_asterisk, struct ast_format_cap *result)
 {
-	format_t formats;
-
-	if (instance->engine->available_formats && (formats = instance->engine->available_formats(instance, to_endpoint, to_asterisk))) {
-		return formats;
+	if (instance->engine->available_formats) {
+		instance->engine->available_formats(instance, to_endpoint, to_asterisk, result);
+		if (!ast_format_cap_is_empty(result)) {
+			return;
+		}
 	}
 
-	return ast_translate_available_formats(to_endpoint, to_asterisk);
+	ast_translate_available_formats(to_endpoint, to_asterisk, result);
 }
 
 int ast_rtp_instance_activate(struct ast_rtp_instance *instance)
diff --git a/main/slinfactory.c b/main/slinfactory.c
index 4da443af5810eac3ca7ef81ba85d48c27a96cf18..f7363ab4bdaf6793c3bb8416823fd644c1bf32f2 100644
--- a/main/slinfactory.c
+++ b/main/slinfactory.c
@@ -36,7 +36,7 @@ void ast_slinfactory_init(struct ast_slinfactory *sf)
 {
 	memset(sf, 0, sizeof(*sf));
 	sf->offset = sf->hold;
-	sf->output_format = AST_FORMAT_SLINEAR;
+	ast_format_set(&sf->output_format, AST_FORMAT_SLINEAR, 0);
 }
 
 int ast_slinfactory_init_rate(struct ast_slinfactory *sf, unsigned int sample_rate) 
@@ -45,10 +45,10 @@ int ast_slinfactory_init_rate(struct ast_slinfactory *sf, unsigned int sample_ra
 	sf->offset = sf->hold;
 	switch (sample_rate) {
 	case 8000:
-		sf->output_format = AST_FORMAT_SLINEAR;
+		ast_format_set(&sf->output_format, AST_FORMAT_SLINEAR, 0);
 		break;
 	case 16000:
-		sf->output_format = AST_FORMAT_SLINEAR16;
+		ast_format_set(&sf->output_format, AST_FORMAT_SLINEAR16, 0);
 		break;
 	default:
 		return -1;
@@ -85,19 +85,19 @@ int ast_slinfactory_feed(struct ast_slinfactory *sf, struct ast_frame *f)
 		return 0;
 	}
 
-	if (f->subclass.codec != sf->output_format) {
-		if (sf->trans && f->subclass.codec != sf->format) {
+	if (ast_format_cmp(&f->subclass.format, &sf->output_format) == AST_FORMAT_CMP_NOT_EQUAL) {
+		if (sf->trans && (ast_format_cmp(&f->subclass.format, &sf->format) == AST_FORMAT_CMP_NOT_EQUAL)) {
 			ast_translator_free_path(sf->trans);
 			sf->trans = NULL;
 		}
 
 		if (!sf->trans) {
-			if (!(sf->trans = ast_translator_build_path(sf->output_format, f->subclass.codec))) {
-				ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", ast_getformatname(f->subclass.codec),
-					ast_getformatname(sf->output_format));
+			if (!(sf->trans = ast_translator_build_path(&sf->output_format, &f->subclass.format))) {
+				ast_log(LOG_WARNING, "Cannot build a path from %s to %s\n", ast_getformatname(&f->subclass.format),
+					ast_getformatname(&sf->output_format));
 				return 0;
 			}
-			sf->format = f->subclass.codec;
+			ast_format_copy(&sf->format, &f->subclass.format);
 		}
 
 		if (!(begin_frame = ast_translate(sf->trans, f, 0))) {
diff --git a/main/translate.c b/main/translate.c
index 61b4a4686d83065aa83c0ba7eb053e896a00adcf..553e70cde2dc16de3feba5d90fcc1c8493c453f5 100644
--- a/main/translate.c
+++ b/main/translate.c
@@ -40,31 +40,26 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
 #include "asterisk/cli.h"
 #include "asterisk/term.h"
 
-#define MAX_RECALC 1000 /* max sample recalc */
+/*! \todo
+ * TODO: sample frames for each supported input format.
+ * We build this on the fly, by taking an SLIN frame and using
+ * the existing converter to play with it.
+ */
+
+/*! max sample recalc */
+#define MAX_RECALC 1000
 
 /*! \brief the list of translators */
 static AST_RWLIST_HEAD_STATIC(translators, ast_translator);
 
-
-/*! \brief these values indicate how a translation path will affect the sample rate
- *
- *  \note These must stay in this order.  They are ordered by most optimal selection first.
- */
-enum path_samp_change {
-	RATE_CHANGE_NONE = 0, /*!< path uses the same sample rate consistently */
-	RATE_CHANGE_UPSAMP = 1, /*!< path will up the sample rate during a translation */
-	RATE_CHANGE_DOWNSAMP = 2, /*!< path will have to down the sample rate during a translation. */
-	RATE_CHANGE_UPSAMP_DOWNSAMP = 3, /*!< path will both up and down the sample rate during translation */
-};
-
 struct translator_path {
-	struct ast_translator *step;	/*!< Next step translator */
-	unsigned int cost;		/*!< Complete cost to destination */
-	unsigned int multistep;		/*!< Multiple conversions required for this translation */
-	enum path_samp_change rate_change; /*!< does this path require a sample rate change, if so what kind. */
+	struct ast_translator *step;       /*!< Next step translator */
+	uint32_t table_cost;               /*!< Complete table cost to destination */
+	uint8_t multistep;                 /*!< Multiple conversions required for this translation */
 };
 
-/*! \brief a matrix that, for any pair of supported formats,
+/*!
+ * \brief a matrix that, for any pair of supported formats,
  * indicates the total cost of translation and the first step.
  * The full path can be reconstricted iterating on the matrix
  * until step->dstfmt == desired_format.
@@ -74,27 +69,202 @@ struct translator_path {
  * Note: the lock in the 'translators' list is also used to protect
  * this structure.
  */
-static struct translator_path tr_matrix[MAX_FORMAT][MAX_FORMAT];
+static struct translator_path **__matrix;
 
-/*! \todo
- * TODO: sample frames for each supported input format.
- * We build this on the fly, by taking an SLIN frame and using
- * the existing converter to play with it.
+/*!
+ * \brief table for converting index to format id values.
+ *
+ * \note this table is protected by the table_lock.
  */
+static int *__indextable;
+
+/*! protects the __indextable for resizing */
+static ast_rwlock_t tablelock;
+
+/* index size starts at this*/
+#define INIT_INDEX 32
+/* index size grows by this as necessary */
+#define GROW_INDEX 16
+
+/*! the current largest index used by the __matrix and __indextable arrays*/
+static int cur_max_index;
+/*! the largest index that can be used in either the __indextable or __matrix before resize must occur */
+static int index_size;
+
+static void matrix_rebuild(int samples);
 
-/*! \brief returns the index of the lowest bit set */
-static force_inline int powerof(format_t d)
+/*!
+ * \internal
+ * \brief converts format id to index value.
+ */
+static int format2index(enum ast_format_id id)
 {
-	int x = ffsll(d);
+	int x;
+
+	ast_rwlock_rdlock(&tablelock);
+	for (x = 0; x < cur_max_index; x++) {
+		if (__indextable[x] == id) {
+			/* format already exists in index2format table */
+			ast_rwlock_unlock(&tablelock);
+			return x;
+		}
+	}
+	ast_rwlock_unlock(&tablelock);
+	return -1; /* not found */
+}
 
-	if (x)
-		return x - 1;
+/*!
+ * \internal
+ * \brief add a new format to the matrix and index table structures.
+ *
+ * \note it is perfectly safe to call this on formats already indexed.
+ *
+ * \retval 0, success
+ * \retval -1, matrix and index table need to be resized
+ */
+static int add_format2index(enum ast_format_id id)
+{
+	if (format2index(id) != -1) {
+		/* format is already already indexed */
+		return 0;
+	}
+
+	ast_rwlock_wrlock(&tablelock);
+	if (cur_max_index == (index_size)) {
+		ast_rwlock_unlock(&tablelock);
+		return -1; /* hit max length */
+	}
+	__indextable[cur_max_index] = id;
+	cur_max_index++;
+	ast_rwlock_unlock(&tablelock);
+
+	return 0;
+}
 
-	ast_log(LOG_WARNING, "No bits set? %llu\n", (unsigned long long) d);
+/*! 
+ * \internal
+ * \brief converts index value back to format id
+ */
+static enum ast_format_id index2format(int index)
+{
+	enum ast_format_id format_id;
+
+	if (index >= cur_max_index) {
+		return 0;
+	}
+	ast_rwlock_rdlock(&tablelock);
+	format_id = __indextable[index];
+	ast_rwlock_unlock(&tablelock);
+
+	return format_id;
+}
+
+/*!
+ * \internal
+ * \brief resize both the matrix and index table so they can represent
+ * more translators
+ *
+ * \note _NO_ locks can be held prior to calling this function
+ *
+ * \retval 0, success
+ * \retval -1, failure.  Old matrix and index table can still be used though
+ */
+static int matrix_resize(int init)
+{
+	struct translator_path **tmp_matrix = NULL;
+	int *tmp_table = NULL;
+	int old_index;
+	int x;
+
+	AST_RWLIST_WRLOCK(&translators);
+	ast_rwlock_wrlock(&tablelock);
+
+	old_index = index_size;
+	if (init) {
+		index_size += INIT_INDEX;
+	} else {
+		index_size += GROW_INDEX;
+	}
+
+	/* make new 2d array of translator_path structures */
+	if (!(tmp_matrix = ast_calloc(1, sizeof(struct translator_path *) * (index_size)))) {
+		goto resize_cleanup;
+	}
+
+	for (x = 0; x < index_size; x++) {
+		if (!(tmp_matrix[x] = ast_calloc(1, sizeof(struct translator_path) * (index_size)))) {
+			goto resize_cleanup;
+		}
+	}
+
+	/* make new index table */
+	if (!(tmp_table = ast_calloc(1, sizeof(int) * index_size))) {
+		goto resize_cleanup;
+	}
+
+	/* if everything went well this far, free the old and use the new */
+	if (!init) {
+		for (x = 0; x < old_index; x++) {
+			ast_free(__matrix[x]);
+		}
+		ast_free(__matrix);
+
+		memcpy(tmp_table, __indextable, sizeof(int) * old_index);
+		ast_free(__indextable);
+	}
+
+	/* now copy them over */
+	__matrix = tmp_matrix;
+	__indextable = tmp_table;
+
+	matrix_rebuild(0);
+	ast_rwlock_unlock(&tablelock);
+	AST_RWLIST_UNLOCK(&translators);
+
+	return 0;
+
+resize_cleanup:
+	ast_rwlock_unlock(&tablelock);
+	AST_RWLIST_UNLOCK(&translators);
+	if (tmp_matrix) {
+		for (x = 0; x < index_size; x++) {
+			ast_free(tmp_matrix[x]);
+		}
+		ast_free(tmp_matrix);
+	}
+	ast_free(tmp_table);
 
 	return -1;
 }
 
+/*!
+ * \internal
+ * \brief reinitialize the __matrix during matrix rebuild
+ *
+ * \note must be protected by the translators list lock
+ */
+static void matrix_clear(void)
+{
+	int x;
+	for (x = 0; x < index_size; x++) {
+		memset(__matrix[x], '\0', sizeof(struct translator_path) * (index_size));
+	}
+}
+
+/*!
+ * \internal
+ * \brief get a matrix entry
+ *
+ * \note This function must be protected by the translators list lock
+ */
+static struct translator_path *matrix_get(unsigned int x, unsigned int y)
+{
+	if (!(x >= 0 && y >= 0)) {
+		return NULL;
+	}
+	return __matrix[x] + y;
+}
+
 /*
  * wrappers around the translator routines.
  */
@@ -151,7 +321,7 @@ static int framein(struct ast_trans_pvt *pvt, struct ast_frame *f)
 {
 	int ret;
 	int samples = pvt->samples;	/* initial value */
-	
+
 	/* Copy the last in jb timing info to the pvt */
 	ast_copy_flags(&pvt->f, f, AST_FRFLAG_HAS_TIMING_INFO);
 	pvt->f.ts = f->ts;
@@ -193,23 +363,23 @@ struct ast_frame *ast_trans_frameout(struct ast_trans_pvt *pvt,
 {
 	struct ast_frame *f = &pvt->f;
 
-	if (samples)
+	if (samples) {
 		f->samples = samples;
-	else {
+	} else {
 		if (pvt->samples == 0)
 			return NULL;
 		f->samples = pvt->samples;
 		pvt->samples = 0;
 	}
-	if (datalen)
+	if (datalen) {
 		f->datalen = datalen;
-	else {
+	} else {
 		f->datalen = pvt->datalen;
 		pvt->datalen = 0;
 	}
 
 	f->frametype = AST_FRAME_VOICE;
-	f->subclass.codec = 1LL << (pvt->t->dstfmt);
+	ast_format_copy(&f->subclass.format, &pvt->t->dst_format);
 	f->mallocd = 0;
 	f->offset = AST_FRIENDLY_OFFSET;
 	f->src = pvt->t->name;
@@ -235,45 +405,56 @@ void ast_translator_free_path(struct ast_trans_pvt *p)
 }
 
 /*! \brief Build a chain of translators based upon the given source and dest formats */
-struct ast_trans_pvt *ast_translator_build_path(format_t dest, format_t source)
+struct ast_trans_pvt *ast_translator_build_path(struct ast_format *dst, struct ast_format *src)
 {
 	struct ast_trans_pvt *head = NULL, *tail = NULL;
-	
-	source = powerof(source);
-	dest = powerof(dest);
+	int src_index, dst_index;
+	struct ast_format tmp_fmt1;
+	struct ast_format tmp_fmt2;
+
+	src_index = format2index(src->id);
+	dst_index = format2index(dst->id);
 
-	if (source == -1 || dest == -1) {
-		ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", source == -1 ? "starting" : "ending");
+	if (src_index == -1 || dst_index == -1) {
+		ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src_index == -1 ? "starting" : "ending");
 		return NULL;
 	}
 
 	AST_RWLIST_RDLOCK(&translators);
 
-	while (source != dest) {
+	while (src_index != dst_index) {
 		struct ast_trans_pvt *cur;
-		struct ast_translator *t = tr_matrix[source][dest].step;
+		struct ast_translator *t = matrix_get(src_index, dst_index)->step;
 		if (!t) {
-			ast_log(LOG_WARNING, "No translator path from %s to %s\n", 
-				ast_getformatname(source), ast_getformatname(dest));
+			int src_id = index2format(src_index);
+			int dst_id = index2format(dst_index);
+			ast_log(LOG_WARNING, "No translator path from %s to %s\n",
+				ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)),
+				ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0)));
 			AST_RWLIST_UNLOCK(&translators);
 			return NULL;
 		}
 		if (!(cur = newpvt(t))) {
+			int src_id = index2format(src_index);
+			int dst_id = index2format(dst_index);
 			ast_log(LOG_WARNING, "Failed to build translator step from %s to %s\n",
-				ast_getformatname(source), ast_getformatname(dest));
-			if (head)
-				ast_translator_free_path(head);	
+				ast_getformatname(ast_format_set(&tmp_fmt1, src_id, 0)),
+				ast_getformatname(ast_format_set(&tmp_fmt2, dst_id, 0)));
+			if (head) {
+				ast_translator_free_path(head);
+			}
 			AST_RWLIST_UNLOCK(&translators);
 			return NULL;
 		}
-		if (!head)
+		if (!head) {
 			head = cur;
-		else
+		} else {
 			tail->next = cur;
+		}
 		tail = cur;
 		cur->nextin = cur->nextout = ast_tv(0, 0);
 		/* Keep going if this isn't the final destination */
-		source = cur->t->dstfmt;
+		src_index = cur->t->dst_fmt_index;
 	}
 
 	AST_RWLIST_UNLOCK(&translators);
@@ -284,7 +465,7 @@ struct ast_trans_pvt *ast_translator_build_path(format_t dest, format_t source)
 struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f, int consume)
 {
 	struct ast_trans_pvt *p = path;
-	struct ast_frame *out = f;
+	struct ast_frame *out;
 	struct timeval delivery;
 	int has_timing_info;
 	long ts;
@@ -296,7 +477,6 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 	len = f->len;
 	seqno = f->seqno;
 
-	/* XXX hmmm... check this below */
 	if (!ast_tvzero(f->delivery)) {
 		if (!ast_tvzero(path->nextin)) {
 			/* Make sure this is in line with what we were expecting */
@@ -316,31 +496,35 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 			path->nextout = f->delivery;
 		}
 		/* Predict next incoming sample */
-		path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(f->subclass.codec)));
+		path->nextin = ast_tvadd(path->nextin, ast_samp2tv(f->samples, ast_format_rate(&f->subclass.format)));
 	}
 	delivery = f->delivery;
-	for ( ; out && p ; p = p->next) {
+	for (out = f; out && p ; p = p->next) {
 		framein(p, out);
-		if (out != f)
+		if (out != f) {
 			ast_frfree(out);
+		}
 		out = p->t->frameout(p);
 	}
-	if (consume)
+	if (consume) {
 		ast_frfree(f);
-	if (out == NULL)
+	}
+	if (out == NULL) {
 		return NULL;
+	}
 	/* we have a frame, play with times */
 	if (!ast_tvzero(delivery)) {
 		/* Regenerate prediction after a discontinuity */
-		if (ast_tvzero(path->nextout))
+		if (ast_tvzero(path->nextout)) {
 			path->nextout = ast_tvnow();
+		}
 
 		/* Use next predicted outgoing timestamp */
 		out->delivery = path->nextout;
-		
+
 		/* Predict next outgoing timestamp from samples in this
 		   frame. */
-		path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(out->subclass.codec)));
+		path->nextout = ast_tvadd(path->nextout, ast_samp2tv(out->samples, ast_format_rate(&out->subclass.format)));
 	} else {
 		out->delivery = ast_tv(0, 0);
 		ast_set2_flag(out, has_timing_info, AST_FRFLAG_HAS_TIMING_INFO);
@@ -351,35 +535,45 @@ struct ast_frame *ast_translate(struct ast_trans_pvt *path, struct ast_frame *f,
 		}
 	}
 	/* Invalidate prediction if we're entering a silence period */
-	if (out->frametype == AST_FRAME_CNG)
+	if (out->frametype == AST_FRAME_CNG) {
 		path->nextout = ast_tv(0, 0);
+	}
 	return out;
 }
 
-/*! \brief compute the cost of a single translation step */
-static void calc_cost(struct ast_translator *t, int seconds)
+/*!
+ * \internal
+ * \brief Compute the computational cost of a single translation step.
+ *
+ * \note This function is only used to decide which translation path to
+ * use between two translators with identical src and dst formats.  Computational
+ * cost acts only as a tie breaker. This is done so hardware translators
+ * can naturally have precedence over software translators.
+ */
+static void generate_computational_cost(struct ast_translator *t, int seconds)
 {
 	int num_samples = 0;
 	struct ast_trans_pvt *pvt;
 	struct rusage start;
 	struct rusage end;
 	int cost;
-	int out_rate = ast_format_rate(t->dstfmt);
+	int out_rate = ast_format_rate(&t->dst_format);
 
-	if (!seconds)
+	if (!seconds) {
 		seconds = 1;
-	
+	}
+
 	/* If they don't make samples, give them a terrible score */
 	if (!t->sample) {
 		ast_log(LOG_WARNING, "Translator '%s' does not produce sample frames.\n", t->name);
-		t->cost = 999999;
+		t->comp_cost = 999999;
 		return;
 	}
 
 	pvt = newpvt(t);
 	if (!pvt) {
 		ast_log(LOG_WARNING, "Translator '%s' appears to be broken and will probably fail.\n", t->name);
-		t->cost = 999999;
+		t->comp_cost = 999999;
 		return;
 	}
 
@@ -391,7 +585,7 @@ static void calc_cost(struct ast_translator *t, int seconds)
 		if (!f) {
 			ast_log(LOG_WARNING, "Translator '%s' failed to produce a sample frame.\n", t->name);
 			destroy(pvt);
-			t->cost = 999999;
+			t->comp_cost = 999999;
 			return;
 		}
 		framein(pvt, f);
@@ -409,72 +603,127 @@ static void calc_cost(struct ast_translator *t, int seconds)
 
 	destroy(pvt);
 
-	t->cost = cost / seconds;
+	t->comp_cost = cost / seconds;
 
-	if (!t->cost)
-		t->cost = 1;
+	if (!t->comp_cost) {
+		t->comp_cost = 1;
+	}
 }
 
-static enum path_samp_change get_rate_change_result(format_t src, format_t dst)
+/*!
+ * \internal
+ *
+ * \brief If no table cost value was pre set by the translator.  An attempt is made to
+ * automatically generate that cost value from the cost table based on our src and
+ * dst formats.
+ *
+ * \note This function allows older translators built before the translation cost
+ * changed away from using onely computational time to continue to be registered
+ * correctly.  It is expected that translators built after the introduction of this
+ * function will manually assign their own table cost value.
+ *
+ * \note This function is safe to use on any audio formats that used to be defined in the
+ * first 64 bits of the old bit field codec representation.
+ *
+ * \retval Table Cost value greater than 0.
+ * \retval 0 on error.
+ */
+static int generate_table_cost(struct ast_format *src, struct ast_format *dst)
 {
 	int src_rate = ast_format_rate(src);
+	int src_ll = 0;
 	int dst_rate = ast_format_rate(dst);
+	int dst_ll = 0;
 
-	/* if src rate is less than dst rate, a sample upgrade is required */
-	if (src_rate < dst_rate) {
-		return RATE_CHANGE_UPSAMP;
+	if ((AST_FORMAT_GET_TYPE(src->id) != AST_FORMAT_TYPE_AUDIO) || (AST_FORMAT_GET_TYPE(dst->id) != AST_FORMAT_TYPE_AUDIO)) {
+		/* This method of generating table cost is limited to audio.
+		 * Translators for media other than audio must manually set their
+		 * table cost. */
+		return 0;
 	}
-
-	/* if src rate is larger than dst rate, a downgrade is required */
-	if (src_rate > dst_rate) {
-		return RATE_CHANGE_DOWNSAMP;
+	if ((src->id == AST_FORMAT_SLINEAR) || (src->id == AST_FORMAT_SLINEAR16)) {
+		src_ll = 1;
+	}
+	if ((dst->id == AST_FORMAT_SLINEAR) || (dst->id == AST_FORMAT_SLINEAR16)) {
+		dst_ll = 1;
 	}
 
-	return RATE_CHANGE_NONE;
+	if (src_ll) {
+		if (dst_ll && (src_rate == dst_rate)) {
+			return AST_TRANS_COST_LL_LL_ORIGSAMP;
+		} else if (!dst_ll && (src_rate == dst_rate)) {
+			return AST_TRANS_COST_LL_LY_ORIGSAMP;
+		} else if (dst_ll && (src_rate < dst_rate)) {
+			return AST_TRANS_COST_LL_LL_UPSAMP;
+		} else if (!dst_ll && (src_rate < dst_rate)) {
+			return AST_TRANS_COST_LL_LY_UPSAMP;
+		} else if (dst_ll && (src_rate > dst_rate)) {
+			return AST_TRANS_COST_LL_LL_DOWNSAMP;
+		} else if (!dst_ll && (src_rate > dst_rate)) {
+			return AST_TRANS_COST_LL_LY_DOWNSAMP;
+		} else {
+			return AST_TRANS_COST_LL_UNKNOWN;
+		}
+	} else {
+		if (dst_ll && (src_rate == dst_rate)) {
+			return AST_TRANS_COST_LY_LL_ORIGSAMP;
+		} else if (!dst_ll && (src_rate == dst_rate)) {
+			return AST_TRANS_COST_LY_LY_ORIGSAMP;
+		} else if (dst_ll && (src_rate < dst_rate)) {
+			return AST_TRANS_COST_LY_LL_UPSAMP;
+		} else if (!dst_ll && (src_rate < dst_rate)) {
+			return AST_TRANS_COST_LY_LY_UPSAMP;
+		} else if (dst_ll && (src_rate > dst_rate)) {
+			return AST_TRANS_COST_LY_LL_DOWNSAMP;
+		} else if (!dst_ll && (src_rate > dst_rate)) {
+			return AST_TRANS_COST_LY_LY_DOWNSAMP;
+		} else {
+			return AST_TRANS_COST_LY_UNKNOWN;
+		}
+	}
 }
 
 /*!
  * \brief rebuild a translation matrix.
  * \note This function expects the list of translators to be locked
 */
-static void rebuild_matrix(int samples)
+static void matrix_rebuild(int samples)
 {
 	struct ast_translator *t;
-	int new_rate_change;
-	int newcost;
+	int newtablecost;
 	int x;      /* source format index */
 	int y;      /* intermediate format index */
 	int z;      /* destination format index */
 
 	ast_debug(1, "Resetting translation matrix\n");
 
-	memset(tr_matrix, '\0', sizeof(tr_matrix));
+	matrix_clear();
 
 	/* first, compute all direct costs */
 	AST_RWLIST_TRAVERSE(&translators, t, list) {
-		if (!t->active)
+		if (!t->active) {
 			continue;
+		}
 
-		x = t->srcfmt;
-		z = t->dstfmt;
-
-		if (samples)
-			calc_cost(t, samples);
+		x = t->src_fmt_index;
+		z = t->dst_fmt_index;
 
-		new_rate_change = get_rate_change_result(1LL << t->srcfmt, 1LL << t->dstfmt);
+		if (samples) {
+			generate_computational_cost(t, samples);
+		}
 
-		/* this translator is the best choice if any of the below are true.
+		/* This new translator is the best choice if any of the below are true.
 		 * 1. no translation path is set between x and z yet.
-		 * 2. the new translation costs less and sample rate is no worse than old one. 
-		 * 3. the new translation has a better sample rate conversion than the old one.
+		 * 2. the new table cost is less.
+		 * 3. the new computational cost is less.  Computational cost is only used
+		 *    to break a tie between two identical translation paths.
 		 */
-		if (!tr_matrix[x][z].step ||
-			((t->cost < tr_matrix[x][z].cost) && (new_rate_change <= tr_matrix[x][z].rate_change)) ||
-			(new_rate_change < tr_matrix[x][z].rate_change)) {
+		if (!matrix_get(x, z)->step ||
+			(t->table_cost < matrix_get(x, z)->step->table_cost) ||
+			(t->comp_cost < matrix_get(x, z)->step->comp_cost)) {
 
-			tr_matrix[x][z].step = t;
-			tr_matrix[x][z].cost = t->cost;
-			tr_matrix[x][z].rate_change = new_rate_change;
+			matrix_get(x, z)->step = t;
+			matrix_get(x, z)->table_cost = t->table_cost;
 		}
 	}
 
@@ -486,81 +735,43 @@ static void rebuild_matrix(int samples)
 	 */
 	for (;;) {
 		int changed = 0;
-		int better_choice = 0;
-		for (x = 0; x < MAX_FORMAT; x++) {      /* source format */
-			for (y = 0; y < MAX_FORMAT; y++) {    /* intermediate format */
-				if (x == y)                     /* skip ourselves */
+		for (x = 0; x < cur_max_index; x++) {      /* source format */
+			for (y = 0; y < cur_max_index; y++) {  /* intermediate format */
+				if (x == y) {                      /* skip ourselves */
 					continue;
-				for (z = 0; z < MAX_FORMAT; z++) {  /* dst format */
-					if (z == x || z == y)       /* skip null conversions */
-						continue;
-					if (!tr_matrix[x][y].step)  /* no path from x to y */
-						continue;
-					if (!tr_matrix[y][z].step)  /* no path from y to z */
-						continue;
-
-					/* Does x->y->z result in a less optimal sample rate change?
-					 * Never downgrade the sample rate conversion quality regardless
-					 * of any cost improvements */
-					if (tr_matrix[x][z].step &&
-						((tr_matrix[x][z].rate_change < tr_matrix[x][y].rate_change) ||
-						(tr_matrix[x][z].rate_change < tr_matrix[y][z].rate_change))) {
+				}
+				for (z = 0; z < cur_max_index; z++) {  /* dst format */
+					if ((z == x || z == y) ||        /* skip null conversions */
+						!matrix_get(x, y)->step ||   /* no path from x to y */
+						!matrix_get(y, z)->step) {   /* no path from y to z */
 						continue;
 					}
 
-					/* is x->y->z a better sample rate confersion that the current x->z? */
-					new_rate_change = tr_matrix[x][y].rate_change + tr_matrix[y][z].rate_change;
-
-					/* calculate cost from x->y->z */
-					newcost = tr_matrix[x][y].cost + tr_matrix[y][z].cost;
-
-					/* Is x->y->z a better choice than x->z?
-					 * There are three conditions for x->y->z to be a better choice than x->z
-					 * 1. if there is no step directly between x->z then x->y->z is the best and only current option.
-					 * 2. if x->y->z costs less and the sample rate conversion is no less optimal.
-					 * 3. if x->y->z results in a more optimal sample rate conversion. */
-					if (!tr_matrix[x][z].step) {
-						better_choice = 1;
-					} else if ((newcost < tr_matrix[x][z].cost) && (new_rate_change <= tr_matrix[x][z].rate_change)) {
-						better_choice = 1;
-					} else if (new_rate_change < tr_matrix[x][z].rate_change) {
-						better_choice = 1;
-					} else {
-						better_choice = 0;
+					/* calculate table cost from x->y->z */
+					newtablecost = matrix_get(x, y)->table_cost + matrix_get(y, z)->table_cost;
+
+					/* if no step already exists between x and z OR the new cost of using the intermediate
+					 * step is cheaper, use this step. */
+					if (!matrix_get(x, z)->step || (newtablecost < matrix_get(x, z)->table_cost)) {
+						struct ast_format tmpx;
+						struct ast_format tmpy;
+						struct ast_format tmpz;
+						matrix_get(x, z)->step = matrix_get(x, y)->step;
+						matrix_get(x, z)->table_cost = newtablecost;
+						matrix_get(x, z)->multistep = 1;
+						changed++;
+						ast_debug(3, "Discovered %d cost path from %s to %s, via %s\n",
+							matrix_get(x, z)->table_cost,
+							ast_getformatname(ast_format_set(&tmpx, index2format(x), 0)),
+							ast_getformatname(ast_format_set(&tmpy, index2format(z), 0)),
+							ast_getformatname(ast_format_set(&tmpz, index2format(y), 0)));
 					}
-
-					if (!better_choice) {
-						continue;
-					}
-					/* ok, we can get from x to z via y with a cost that
-					   is the sum of the transition from x to y and from y to z */
-					tr_matrix[x][z].step = tr_matrix[x][y].step;
-					tr_matrix[x][z].cost = newcost;
-					tr_matrix[x][z].multistep = 1;
-
-					/* now calculate what kind of sample rate change is required for this multi-step path
-					 * 
-					 * if both paths require a change in rate, and they are not in the same direction
-					 * then this is a up sample down sample conversion scenario. */
-					if ((tr_matrix[x][y].rate_change > RATE_CHANGE_NONE) &&
-						(tr_matrix[y][z].rate_change > RATE_CHANGE_NONE) &&
-						(tr_matrix[x][y].rate_change != tr_matrix[y][z].rate_change)) {
-
-						tr_matrix[x][z].rate_change = RATE_CHANGE_UPSAMP_DOWNSAMP;
-					} else {
-						/* else just set the rate change to whichever is worse */
-						tr_matrix[x][z].rate_change = tr_matrix[x][y].rate_change > tr_matrix[y][z].rate_change
-							? tr_matrix[x][y].rate_change : tr_matrix[y][z].rate_change;
-					}
-
-					ast_debug(3, "Discovered %d cost path from %s to %s, via %s\n", tr_matrix[x][z].cost,
-						  ast_getformatname(1LL << x), ast_getformatname(1LL << z), ast_getformatname(1LL << y));
-					changed++;
 				}
 			}
 		}
-		if (!changed)
+		if (!changed) {
 			break;
+		}
 	}
 }
 
@@ -572,11 +783,11 @@ const char *ast_translate_path_to_str(struct ast_trans_pvt *p, struct ast_str **
 		return "";
 	}
 
-	ast_str_set(str, 0, "%s", ast_getformatname(1LL << p->t->srcfmt));
+	ast_str_set(str, 0, "%s", ast_getformatname(&p->t->src_format));
 
 	while ( (p = pn) ) {
 		pn = p->next;
-		ast_str_append(str, 0, "->%s", ast_getformatname(1LL << p->t->dstfmt));
+		ast_str_append(str, 0, "->%s", ast_getformatname(&p->t->dst_format));
 	}
 
 	return ast_str_buffer(*str);
@@ -592,7 +803,7 @@ static char *complete_trans_path_choice(const char *line, const char *word, int
 	const struct ast_format_list *format_list = ast_get_format_list(&len);
 
 	for (i = 0; i < len; i++) {
-		if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK)) {
+		if (AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) {
 			continue;
 		}
 		if (!strncasecmp(word, format_list[i].name, wordlen) && ++which > state) {
@@ -603,165 +814,81 @@ static char *complete_trans_path_choice(const char *line, const char *word, int
 	return ret;
 }
 
-static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+static void handle_cli_recalc(struct ast_cli_args *a)
 {
-#define SHOW_TRANS 64
-	static const char * const option1[] = { "recalc", "paths", NULL };
-	int x, y, z;
-	int curlen = 0, longest = 0, magnitude[SHOW_TRANS] = { 0, };
+	int time = a->argv[4] ? atoi(a->argv[4]) : 1;
 
-	switch (cmd) {
-	case CLI_INIT:
-		e->command = "core show translation";
-		e->usage =
-			"Usage: 'core show translation' can be used in two ways.\n"
-			"       1. 'core show translation [recalc [<recalc seconds>]]\n"
-			"          Displays known codec translators and the cost associated\n"
-			"          with each conversion.  If the argument 'recalc' is supplied along\n"
-			"          with optional number of seconds to test a new test will be performed\n"
-			"          as the chart is being displayed.\n"
-			"       2. 'core show translation paths [codec]'\n"
-			"           This will display all the translation paths associated with a codec\n";
-		return NULL;
-	case CLI_GENERATE:
-		if (a->pos == 3) {
-			return ast_cli_complete(a->word, option1, a->n);
-		}
-		if (a->pos == 4 && !strcasecmp(a->argv[3], option1[1])) {
-			return complete_trans_path_choice(a->line, a->word, a->pos, a->n);
-		}
-		return NULL;
+	if (time <= 0) {
+		ast_cli(a->fd, "         Recalc must be greater than 0.  Defaulting to 1.\n");
+		time = 1;
 	}
 
-	if (a->argc > 5)
-		return CLI_SHOWUSAGE;
-
-	if (a->argv[3] && !strcasecmp(a->argv[3], option1[1]) && a->argc == 5) {
-		format_t input_src = 0;
-		format_t src = 0;
-		size_t len = 0;
-		int dst;
-		int i;
-		const struct ast_format_list *format_list = ast_get_format_list(&len);
-		struct ast_str *str = ast_str_alloca(256);
-		struct ast_translator *step;
-
-		for (i = 0; i < len; i++) {
-			if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK)) {
-				continue;
-			}
-			if (!strncasecmp(format_list[i].name, a->argv[4], strlen(format_list[i].name))) {
-				input_src = format_list[i].bits;
-			}
-		}
-
-		if (!input_src) {
-			ast_cli(a->fd, "Source codec \"%s\" is not found.\n", a->argv[4]);
-			return CLI_FAILURE;
-		}
-
-		AST_RWLIST_RDLOCK(&translators);
-		ast_cli(a->fd, "--- Translation paths SRC Codec \"%s\" sample rate %d ---\n", a->argv[4], ast_format_rate(input_src));
-		for (i = 0; i < len; i++) {
-			if (!(format_list[i].bits & AST_FORMAT_AUDIO_MASK) || (format_list[i].bits == input_src)) {
-				continue;
-			}
-			dst = powerof(format_list[i].bits);
-			src = powerof(input_src);
-			ast_str_reset(str);
-			if (tr_matrix[src][dst].step) {
-				ast_str_append(&str, 0, "%s", ast_getformatname(1LL << tr_matrix[src][dst].step->srcfmt));
-				while (src != dst) {
-					step = tr_matrix[src][dst].step;
-					if (!step) {
-						ast_str_reset(str);
-						break;
-					}
-					ast_str_append(&str, 0, "->%s", ast_getformatname(1LL << step->dstfmt));
-					src = step->dstfmt;
-				}
-			}
-
-			if (ast_strlen_zero(ast_str_buffer(str))) {
-				ast_str_set(&str, 0, "No Translation Path");
-			}
-
-			ast_cli(a->fd, "\t%-10.10s To %-10.10s: %-60.60s\n", a->argv[4], format_list[i].name, ast_str_buffer(str));
-		}
-		AST_RWLIST_UNLOCK(&translators);
-
-		return CLI_SUCCESS;
-	} else if (a->argv[3] && !strcasecmp(a->argv[3], "recalc")) {
-		z = a->argv[4] ? atoi(a->argv[4]) : 1;
-
-		if (z <= 0) {
-			ast_cli(a->fd, "         Recalc must be greater than 0.  Defaulting to 1.\n");
-			z = 1;
-		}
-
-		if (z > MAX_RECALC) {
-			ast_cli(a->fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", z - MAX_RECALC, MAX_RECALC);
-			z = MAX_RECALC;
-		}
-		ast_cli(a->fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", z);
-		AST_RWLIST_WRLOCK(&translators);
-		rebuild_matrix(z);
-		AST_RWLIST_UNLOCK(&translators);
-	} else if (a->argc > 3)
-		return CLI_SHOWUSAGE;
+	if (time > MAX_RECALC) {
+		ast_cli(a->fd, "         Maximum limit of recalc exceeded by %d, truncating value to %d\n", time - MAX_RECALC, MAX_RECALC);
+		time = MAX_RECALC;
+	}
+	ast_cli(a->fd, "         Recalculating Codec Translation (number of sample seconds: %d)\n\n", time);
+	AST_RWLIST_WRLOCK(&translators);
+	matrix_rebuild(time);
+	AST_RWLIST_UNLOCK(&translators);
+}
 
+static char *handle_show_translation_table(struct ast_cli_args *a)
+{
+	int x, y;
+	int curlen = 0, longest = 0;
+	struct ast_format tmp_fmt;
 	AST_RWLIST_RDLOCK(&translators);
-
 	ast_cli(a->fd, "         Translation times between formats (in microseconds) for one second of data\n");
 	ast_cli(a->fd, "          Source Format (Rows) Destination Format (Columns)\n\n");
+
 	/* Get the length of the longest (usable?) codec name, so we know how wide the left side should be */
-	for (x = 0; x < SHOW_TRANS; x++) {
+	for (x = 0; x < cur_max_index; x++) {
 		/* translation only applies to audio right now. */
-		if (!(AST_FORMAT_AUDIO_MASK & (1LL << (x))))
+		if (AST_FORMAT_GET_TYPE(index2format(x)) != AST_FORMAT_TYPE_AUDIO)
 			continue;
-		curlen = strlen(ast_getformatname(1LL << (x)));
-		if (curlen > longest)
+		curlen = strlen(ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)));
+		if (curlen > longest) {
 			longest = curlen;
-		for (y = 0; y < SHOW_TRANS; y++) {
-			if (!(AST_FORMAT_AUDIO_MASK & (1LL << (y))))
-				continue;
-			if (tr_matrix[x][y].cost > pow(10, magnitude[x])) {
-				magnitude[y] = floor(log10(tr_matrix[x][y].cost));
-			}
 		}
 	}
-	for (x = -1; x < SHOW_TRANS; x++) {
+
+	for (x = -1; x < cur_max_index; x++) {
 		struct ast_str *out = ast_str_alloca(256);
 		/* translation only applies to audio right now. */
-		if (x >= 0 && !(AST_FORMAT_AUDIO_MASK & (1LL << (x))))
+		if (x >= 0 && (AST_FORMAT_GET_TYPE(index2format(x)) != AST_FORMAT_TYPE_AUDIO)) {
 			continue;
+		}
 		/*Go ahead and move to next iteration if dealing with an unknown codec*/
-		if(x >= 0 && !strcmp(ast_getformatname(1LL << (x)), "unknown"))
+		if (x >= 0 && !strcmp(ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)), "unknown")) {
 			continue;
+		}
 		ast_str_set(&out, -1, " ");
-		for (y = -1; y < SHOW_TRANS; y++) {
+		for (y = -1; y < cur_max_index; y++) {
 			/* translation only applies to audio right now. */
-			if (y >= 0 && !(AST_FORMAT_AUDIO_MASK & (1LL << (y))))
+			if (y >= 0 && (AST_FORMAT_GET_TYPE(index2format(y)) != AST_FORMAT_TYPE_AUDIO)) {
 				continue;
+			}
 			/*Go ahead and move to next iteration if dealing with an unknown codec*/
-			if (y >= 0 && !strcmp(ast_getformatname(1LL << (y)), "unknown"))
+			if (y >= 0 && !strcmp(ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)), "unknown")) {
 				continue;
-			if (y >= 0)
-				curlen = strlen(ast_getformatname(1LL << (y)));
-			if (y >= 0 && magnitude[y] + 1 > curlen) {
-				curlen = magnitude[y] + 1;
 			}
-			if (curlen < 5)
+			if (y >= 0) {
+				curlen = strlen(ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)));
+			}
+			if (curlen < 5) {
 				curlen = 5;
-			if (x >= 0 && y >= 0 && tr_matrix[x][y].step) {
+			}
+
+			if (x >= 0 && y >= 0 && matrix_get(x, y)->step) {
 				/* Actual codec output */
-				ast_str_append(&out, -1, "%*d", curlen + 1, tr_matrix[x][y].cost);
+				ast_str_append(&out, -1, "%*d", curlen + 1, (matrix_get(x, y)->table_cost/100));
 			} else if (x == -1 && y >= 0) {
 				/* Top row - use a dynamic size */
-				ast_str_append(&out, -1, "%*s", curlen + 1, ast_getformatname(1LL << (y)) );
+				ast_str_append(&out, -1, "%*s", curlen + 1, ast_getformatname(ast_format_set(&tmp_fmt, index2format(y), 0)));
 			} else if (y == -1 && x >= 0) {
 				/* Left column - use a static size. */
-				ast_str_append(&out, -1, "%*s", longest, ast_getformatname(1LL << (x)) );
+				ast_str_append(&out, -1, "%*s", longest, ast_getformatname(ast_format_set(&tmp_fmt, index2format(x), 0)));
 			} else if (x >= 0 && y >= 0) {
 				/* Codec not supported */
 				ast_str_append(&out, -1, "%*s", curlen + 1, "-");
@@ -777,6 +904,106 @@ static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd,
 	return CLI_SUCCESS;
 }
 
+static char *handle_show_translation_path(struct ast_cli_args *a)
+{
+	struct ast_format input_src_format;
+	size_t len = 0;
+	int i;
+	const struct ast_format_list *format_list = ast_get_format_list(&len);
+	struct ast_str *str = ast_str_alloca(256);
+	struct ast_translator *step;
+
+	ast_format_clear(&input_src_format);
+
+	for (i = 0; i < len; i++) {
+		if (AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) {
+			continue;
+		}
+		if (!strncasecmp(format_list[i].name, a->argv[4], strlen(format_list[i].name))) {
+			ast_format_set(&input_src_format, format_list[i].id, 0);
+		}
+	}
+
+	if (!input_src_format.id) {
+		ast_cli(a->fd, "Source codec \"%s\" is not found.\n", a->argv[4]);
+		return CLI_FAILURE;
+	}
+
+	AST_RWLIST_RDLOCK(&translators);
+	ast_cli(a->fd, "--- Translation paths SRC Codec \"%s\" sample rate %d ---\n", a->argv[4], ast_format_rate(&input_src_format));
+	for (i = 0; i < len; i++) {
+		int src;
+		int dst;
+		if ((AST_FORMAT_GET_TYPE(format_list[i].id) != AST_FORMAT_TYPE_AUDIO) || (format_list[i].id == input_src_format.id)) {
+			continue;
+		}
+		dst = format2index(format_list[i].id);
+		src = format2index(input_src_format.id);
+		ast_str_reset(str);
+		if ((len >= cur_max_index) && (src != -1) && (dst != -1) && matrix_get(src, dst)->step) {
+			ast_str_append(&str, 0, "%s", ast_getformatname(&matrix_get(src, dst)->step->src_format));
+			while (src != dst) {
+				step = matrix_get(src, dst)->step;
+				if (!step) {
+					ast_str_reset(str);
+					break;
+				}
+				ast_str_append(&str, 0, "->%s", ast_getformatname(&step->dst_format));
+				src = step->dst_fmt_index;
+			}
+		}
+
+		if (ast_strlen_zero(ast_str_buffer(str))) {
+			ast_str_set(&str, 0, "No Translation Path");
+		}
+		ast_cli(a->fd, "\t%-10.10s To %-10.10s: %-60.60s\n", a->argv[4], format_list[i].name, ast_str_buffer(str));
+	}
+	AST_RWLIST_UNLOCK(&translators);
+
+	return CLI_SUCCESS;
+}
+
+static char *handle_cli_core_show_translation(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+	static const char * const option[] = { "recalc", "paths", NULL };
+
+	switch (cmd) {
+	case CLI_INIT:
+		e->command = "core show translation";
+		e->usage =
+			"Usage: 'core show translation' can be used in two ways.\n"
+			"       1. 'core show translation [recalc [<recalc seconds>]]\n"
+			"          Displays known codec translators and the cost associated\n"
+			"          with each conversion.  If the argument 'recalc' is supplied along\n"
+			"          with optional number of seconds to test a new test will be performed\n"
+			"          as the chart is being displayed.\n"
+			"       2. 'core show translation paths [codec]'\n"
+			"           This will display all the translation paths associated with a codec\n";
+		return NULL;
+	case CLI_GENERATE:
+		if (a->pos == 3) {
+			return ast_cli_complete(a->word, option, a->n);
+		}
+		if (a->pos == 4 && !strcasecmp(a->argv[3], option[1])) {
+			return complete_trans_path_choice(a->line, a->word, a->pos, a->n);
+		}
+		return NULL;
+	}
+
+	if (a->argc > 5)
+		return CLI_SHOWUSAGE;
+
+	if (a->argv[3] && !strcasecmp(a->argv[3], option[1]) && a->argc == 5) { /* show paths */
+		return handle_show_translation_path(a);
+	} else if (a->argv[3] && !strcasecmp(a->argv[3], option[0])) { /* recalc and then fall through to show table */
+		handle_cli_recalc(a);
+	} else if (a->argc > 3) { /* wrong input */
+		return CLI_SHOWUSAGE;
+	}
+
+	return handle_show_translation_table(a);
+}
+
 static struct ast_cli_entry cli_translate[] = {
 	AST_CLI_DEFINE(handle_cli_core_show_translation, "Display translation matrix")
 };
@@ -784,10 +1011,18 @@ static struct ast_cli_entry cli_translate[] = {
 /*! \brief register codec translator */
 int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
 {
-	static int added_cli = 0;
 	struct ast_translator *u;
 	char tmp[80];
 
+	if (add_format2index(t->src_format.id) || add_format2index(t->dst_format.id)) {
+		if (matrix_resize(0)) {
+			ast_log(LOG_WARNING, "Translator matrix can not represent any more translators.  Out of resources.\n");
+			return -1;
+		}
+		add_format2index(t->src_format.id);
+		add_format2index(t->dst_format.id);
+	}
+
 	if (!mod) {
 		ast_log(LOG_WARNING, "Missing module pointer, you need to supply one\n");
 		return -1;
@@ -797,24 +1032,28 @@ int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
 		ast_log(LOG_WARNING, "empty buf size, you need to supply one\n");
 		return -1;
 	}
+	if (!t->table_cost && !(t->table_cost = generate_table_cost(&t->src_format, &t->dst_format))) {
+		ast_log(LOG_WARNING, "Table cost could not be generated for %s, "
+			"Please set table_cost variable on translator.\n", t->name);
+		return -1;
+	}
 
 	t->module = mod;
-
-	t->srcfmt = powerof(t->srcfmt);
-	t->dstfmt = powerof(t->dstfmt);
+	t->src_fmt_index = format2index(t->src_format.id);
+	t->dst_fmt_index = format2index(t->dst_format.id);
 	t->active = 1;
 
-	if (t->srcfmt == -1 || t->dstfmt == -1) {
-		ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->srcfmt == -1 ? "starting" : "ending");
+	if (t->src_fmt_index == -1 || t->dst_fmt_index == -1) {
+		ast_log(LOG_WARNING, "Invalid translator path: (%s codec is not valid)\n", t->src_fmt_index == -1 ? "starting" : "ending");
 		return -1;
 	}
-	if (t->srcfmt >= MAX_FORMAT) {
-		ast_log(LOG_WARNING, "Source format %s is larger than MAX_FORMAT\n", ast_getformatname(t->srcfmt));
+	if (t->src_fmt_index >= cur_max_index) {
+		ast_log(LOG_WARNING, "Source format %s is larger than cur_max_index\n", ast_getformatname(&t->src_format));
 		return -1;
 	}
 
-	if (t->dstfmt >= MAX_FORMAT) {
-		ast_log(LOG_WARNING, "Destination format %s is larger than MAX_FORMAT\n", ast_getformatname(t->dstfmt));
+	if (t->dst_fmt_index >= cur_max_index) {
+		ast_log(LOG_WARNING, "Destination format %s is larger than cur_max_index\n", ast_getformatname(&t->dst_format));
 		return -1;
 	}
 
@@ -829,28 +1068,24 @@ int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
 		t->buf_size = ((t->buf_size + align - 1) / align) * align;
 	}
 
-	if (t->frameout == NULL)
+	if (t->frameout == NULL) {
 		t->frameout = default_frameout;
-  
-	calc_cost(t, 1);
+	}
 
-	ast_verb(2, "Registered translator '%s' from format %s to %s, cost %d\n",
-			    term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
-			    ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt), t->cost);
+	generate_computational_cost(t, 1);
 
-	if (!added_cli) {
-		ast_cli_register_multiple(cli_translate, ARRAY_LEN(cli_translate));
-		added_cli++;
-	}
+	ast_verb(2, "Registered translator '%s' from format %s to %s, table cost, %d, computational cost %d\n",
+			    term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
+			    ast_getformatname(&t->src_format), ast_getformatname(&t->dst_format), t->table_cost, t->comp_cost);
 
 	AST_RWLIST_WRLOCK(&translators);
 
 	/* find any existing translators that provide this same srcfmt/dstfmt,
-	   and put this one in order based on cost */
+	   and put this one in order based on computational cost */
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
-		if ((u->srcfmt == t->srcfmt) &&
-		    (u->dstfmt == t->dstfmt) &&
-		    (u->cost > t->cost)) {
+		if ((u->src_fmt_index == t->src_fmt_index) &&
+		    (u->dst_fmt_index == t->dst_fmt_index) &&
+		    (u->comp_cost > t->comp_cost)) {
 			AST_RWLIST_INSERT_BEFORE_CURRENT(t, list);
 			t = NULL;
 			break;
@@ -860,10 +1095,11 @@ int __ast_register_translator(struct ast_translator *t, struct ast_module *mod)
 
 	/* if no existing translator was found for this format combination,
 	   add it to the beginning of the list */
-	if (t)
+	if (t) {
 		AST_RWLIST_INSERT_HEAD(&translators, t, list);
+	}
 
-	rebuild_matrix(0);
+	matrix_rebuild(0);
 
 	AST_RWLIST_UNLOCK(&translators);
 
@@ -881,15 +1117,19 @@ int ast_unregister_translator(struct ast_translator *t)
 	AST_RWLIST_TRAVERSE_SAFE_BEGIN(&translators, u, list) {
 		if (u == t) {
 			AST_RWLIST_REMOVE_CURRENT(list);
-			ast_verb(2, "Unregistered translator '%s' from format %s to %s\n", term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)), ast_getformatname(1LL << t->srcfmt), ast_getformatname(1LL << t->dstfmt));
+			ast_verb(2, "Unregistered translator '%s' from format %s to %s\n",
+				term_color(tmp, t->name, COLOR_MAGENTA, COLOR_BLACK, sizeof(tmp)),
+				ast_getformatname(&t->src_format),
+				ast_getformatname(&t->dst_format));
 			found = 1;
 			break;
 		}
 	}
 	AST_RWLIST_TRAVERSE_SAFE_END;
 
-	if (found)
-		rebuild_matrix(0);
+	if (found) {
+		matrix_rebuild(0);
+	}
 
 	AST_RWLIST_UNLOCK(&translators);
 
@@ -900,7 +1140,7 @@ void ast_translator_activate(struct ast_translator *t)
 {
 	AST_RWLIST_WRLOCK(&translators);
 	t->active = 1;
-	rebuild_matrix(0);
+	matrix_rebuild(0);
 	AST_RWLIST_UNLOCK(&translators);
 }
 
@@ -908,93 +1148,93 @@ void ast_translator_deactivate(struct ast_translator *t)
 {
 	AST_RWLIST_WRLOCK(&translators);
 	t->active = 0;
-	rebuild_matrix(0);
+	matrix_rebuild(0);
 	AST_RWLIST_UNLOCK(&translators);
 }
 
 /*! \brief Calculate our best translator source format, given costs, and a desired destination */
-format_t ast_translator_best_choice(format_t *dst, format_t *srcs)
+int ast_translator_best_choice(struct ast_format_cap *dst_cap,
+	struct ast_format_cap *src_cap,
+	struct ast_format *dst_fmt_out,
+	struct ast_format *src_fmt_out)
 {
-	int x,y;
-	int better = 0;
-	int besttime = INT_MAX;
-	int beststeps = INT_MAX;
-	unsigned int best_rate_change = INT_MAX;
-	format_t best = -1;
-	format_t bestdst = 0;
-	format_t cur, cursrc;
-	format_t common = ((*dst) & (*srcs)) & AST_FORMAT_AUDIO_MASK;	/* are there common formats ? */
-
-	if (common) { /* yes, pick one and return */
-		for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
-			if (!(cur & common)) {
-				continue;
-			}
-
+	unsigned int besttablecost = INT_MAX;
+	unsigned int beststeps = INT_MAX;
+	struct ast_format best;
+	struct ast_format bestdst;
+	struct ast_format_cap *joint_cap = ast_format_cap_joint(dst_cap, src_cap);
+	ast_format_clear(&best);
+	ast_format_clear(&bestdst);
+
+	if (joint_cap) { /* yes, pick one and return */
+		struct ast_format tmp_fmt;
+		ast_format_cap_iter_start(joint_cap);
+		while (!ast_format_cap_iter_next(joint_cap, &tmp_fmt)) {
 			/* We are guaranteed to find one common format. */
-			if (best == -1) {
-				best = cur;
+			if (!best.id) {
+				ast_format_copy(&best, &tmp_fmt);
 				continue;
 			}
 			/* If there are multiple common formats, pick the one with the highest sample rate */
-			if (ast_format_rate(best) < ast_format_rate(cur)) {
-				best = cur;
+			if (ast_format_rate(&best) < ast_format_rate(&tmp_fmt)) {
+				ast_format_copy(&best, &tmp_fmt);
 				continue;
 			}
+
 		}
+		ast_format_cap_iter_end(joint_cap);
+
 		/* We are done, this is a common format to both. */
-		*srcs = *dst = best;
+		ast_format_copy(dst_fmt_out, &best);
+		ast_format_copy(src_fmt_out, &best);
+		ast_format_cap_destroy(joint_cap);
 		return 0;
 	} else {      /* No, we will need to translate */
+		struct ast_format cur_dst;
+		struct ast_format cur_src;
 		AST_RWLIST_RDLOCK(&translators);
-		for (cur = 1, y = 0; y <= MAX_AUDIO_FORMAT; cur <<= 1, y++) {
-			if (! (cur & *dst)) {
-				continue;
-			}
-			for (cursrc = 1, x = 0; x <= MAX_AUDIO_FORMAT; cursrc <<= 1, x++) {
-				if (!(*srcs & cursrc) || !tr_matrix[x][y].step) {
-					continue;
-				}
 
-				/* This is a better choice if any of the following are true.
-				 * 1. The sample rate conversion is better than the current pick.
-				 * 2. the sample rate conversion is no worse than the current pick and the cost or multistep is better
-				 */
-				better = 0;
-				if (tr_matrix[x][y].rate_change < best_rate_change) {
-					better = 1; /* this match has a better rate conversion */
+		ast_format_cap_iter_start(dst_cap);
+		while (!ast_format_cap_iter_next(dst_cap, &cur_dst)) {
+			ast_format_cap_iter_start(src_cap);
+			while (!ast_format_cap_iter_next(src_cap, &cur_src)) {
+				int x = format2index(cur_src.id);
+				int y = format2index(cur_dst.id);
+				if (x < 0 || y < 0) {
+					continue;
 				}
-				if ((tr_matrix[x][y].rate_change <= best_rate_change) &&
-					(tr_matrix[x][y].cost < besttime || tr_matrix[x][y].multistep < beststeps)) {
-					better = 1; /* this match has no worse rate conversion and the conversion cost is less */
+				if (!matrix_get(x, y) || !(matrix_get(x, y)->step)) {
+					continue;
 				}
-				if (better) {
+				if (((matrix_get(x, y)->table_cost < besttablecost) || (matrix_get(x, y)->multistep < beststeps))) {
 					/* better than what we have so far */
-					best = cursrc;
-					bestdst = cur;
-					besttime = tr_matrix[x][y].cost;
-					beststeps = tr_matrix[x][y].multistep;
-					best_rate_change = tr_matrix[x][y].rate_change;
+					ast_format_copy(&best, &cur_src);
+					ast_format_copy(&bestdst, &cur_dst);
+					besttablecost = matrix_get(x, y)->table_cost;
+					beststeps = matrix_get(x, y)->multistep;
 				}
 			}
+			ast_format_cap_iter_end(src_cap);
 		}
+
+		ast_format_cap_iter_end(dst_cap);
 		AST_RWLIST_UNLOCK(&translators);
-		if (best > -1) {
-			*srcs = best;
-			*dst = bestdst;
-			best = 0;
+		if (best.id) {
+			ast_format_copy(dst_fmt_out, &bestdst);
+			ast_format_copy(src_fmt_out, &best);
+			return 0;
 		}
-		return best;
+		return -1;
 	}
 }
 
-unsigned int ast_translate_path_steps(format_t dest, format_t src)
+unsigned int ast_translate_path_steps(struct ast_format *dst_format, struct ast_format *src_format)
 {
 	unsigned int res = -1;
-
+	int src, dest;
 	/* convert bitwise format numbers into array indices */
-	src = powerof(src);
-	dest = powerof(dest);
+	src = format2index(src_format->id);
+	dest = format2index(dst_format->id);
 
 	if (src == -1 || dest == -1) {
 		ast_log(LOG_WARNING, "No translator path: (%s codec is not valid)\n", src == -1 ? "starting" : "ending");
@@ -1002,97 +1242,123 @@ unsigned int ast_translate_path_steps(format_t dest, format_t src)
 	}
 	AST_RWLIST_RDLOCK(&translators);
 
-	if (tr_matrix[src][dest].step)
-		res = tr_matrix[src][dest].multistep + 1;
+	if (matrix_get(src, dest)->step) {
+		res = matrix_get(src, dest)->multistep + 1;
+	}
 
 	AST_RWLIST_UNLOCK(&translators);
 
 	return res;
 }
 
-format_t ast_translate_available_formats(format_t dest, format_t src)
+void ast_translate_available_formats(struct ast_format_cap *dest, struct ast_format_cap *src, struct ast_format_cap *result)
 {
-	format_t res = dest;
-	format_t x;
-	format_t src_audio = src & AST_FORMAT_AUDIO_MASK;
-	format_t src_video = src & AST_FORMAT_VIDEO_MASK;
+	struct ast_format tmp_fmt;
+	struct ast_format cur_src;
+	int src_audio = 0;
+	int src_video = 0;
+	int index;
+
+	ast_format_cap_copy(result, dest);
 
 	/* if we don't have a source format, we just have to try all
 	   possible destination formats */
-	if (!src)
-		return dest;
+	if (!src) {
+		return;
+	}
 
-	/* If we have a source audio format, get its format index */
-	if (src_audio)
-		src_audio = powerof(src_audio);
+	ast_format_cap_iter_start(src);
+	while (!ast_format_cap_iter_next(src, &cur_src)) {
+		/* If we have a source audio format, get its format index */
+		if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_AUDIO) {
+			src_audio = format2index(cur_src.id);
+		}
 
-	/* If we have a source video format, get its format index */
-	if (src_video)
-		src_video = powerof(src_video);
+		/* If we have a source video format, get its format index */
+		if (AST_FORMAT_GET_TYPE(cur_src.id) == AST_FORMAT_TYPE_VIDEO) {
+			src_video = format2index(cur_src.id);
+		}
 
-	AST_RWLIST_RDLOCK(&translators);
+		AST_RWLIST_RDLOCK(&translators);
 
-	/* For a given source audio format, traverse the list of
-	   known audio formats to determine whether there exists
-	   a translation path from the source format to the
-	   destination format. */
-	for (x = 1LL; src_audio && x > 0; x <<= 1) {
-		if (!(x & AST_FORMAT_AUDIO_MASK)) {
-			continue;
-		}
+		/* For a given source audio format, traverse the list of
+		   known audio formats to determine whether there exists
+		   a translation path from the source format to the
+		   destination format. */
+		for (index = 0; (src_audio >= 0) && index < cur_max_index; index++) {
+			ast_format_set(&tmp_fmt, index2format(index), 0);
 
-		/* if this is not a desired format, nothing to do */
-		if (!(dest & x))
-			continue;
+			if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_AUDIO) {
+				continue;
+			}
 
-		/* if the source is supplying this format, then
-		   we can leave it in the result */
-		if (src & x)
-			continue;
+			/* if this is not a desired format, nothing to do */
+			if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) {
+				continue;
+			}
 
-		/* if we don't have a translation path from the src
-		   to this format, remove it from the result */
-		if (!tr_matrix[src_audio][powerof(x)].step) {
-			res &= ~x;
-			continue;
-		}
+			/* if the source is supplying this format, then
+			   we can leave it in the result */
+			if (ast_format_cap_iscompatible(src, &tmp_fmt)) {
+				continue;
+			}
 
-		/* now check the opposite direction */
-		if (!tr_matrix[powerof(x)][src_audio].step)
-			res &= ~x;
-	}
+			/* if we don't have a translation path from the src
+			   to this format, remove it from the result */
+			if (!matrix_get(src_audio, index)->step) {
+				ast_format_cap_remove_byid(result, tmp_fmt.id);
+				continue;
+			}
 
-	/* For a given source video format, traverse the list of
-	   known video formats to determine whether there exists
-	   a translation path from the source format to the
-	   destination format. */
-	for (x = 1LL; src_video && x > 0; x <<= 1) {
-		if (!(x & AST_FORMAT_VIDEO_MASK)) {
-			continue;
+			/* now check the opposite direction */
+			if (!matrix_get(index, src_audio)->step) {
+				ast_format_cap_remove_byid(result, tmp_fmt.id);
+			}
 		}
 
-		/* if this is not a desired format, nothing to do */
-		if (!(dest & x))
-			continue;
+		/* For a given source video format, traverse the list of
+		   known video formats to determine whether there exists
+		   a translation path from the source format to the
+		   destination format. */
+		for (index = 0; (src_video >= 0) && index < cur_max_index; index++) {
+			ast_format_set(&tmp_fmt, index2format(index), 0);
+			if (AST_FORMAT_GET_TYPE(tmp_fmt.id) != AST_FORMAT_TYPE_VIDEO) {
+				continue;
+			}
 
-		/* if the source is supplying this format, then
-		   we can leave it in the result */
-		if (src & x)
-			continue;
+			/* if this is not a desired format, nothing to do */
+			if (!ast_format_cap_iscompatible(dest, &tmp_fmt)) {
+				continue;
+			}
 
-		/* if we don't have a translation path from the src
-		   to this format, remove it from the result */
-		if (!tr_matrix[src_video][powerof(x)].step) {
-			res &= ~x;
-			continue;
-		}
+			/* if the source is supplying this format, then
+			   we can leave it in the result */
+			if (ast_format_cap_iscompatible(src, &tmp_fmt)) {
+				continue;
+			}
 
-		/* now check the opposite direction */
-		if (!tr_matrix[powerof(x)][src_video].step)
-			res &= ~x;
-	}
+			/* if we don't have a translation path from the src
+			   to this format, remove it from the result */
+			if (!matrix_get(src_video, index)->step) {
+				ast_format_cap_remove_byid(result, tmp_fmt.id);
+				continue;
+			}
 
-	AST_RWLIST_UNLOCK(&translators);
+			/* now check the opposite direction */
+			if (!matrix_get(index, src_video)->step) {
+				ast_format_cap_remove_byid(result, tmp_fmt.id);
+			}
+		}
+		AST_RWLIST_UNLOCK(&translators);
+	}
+	ast_format_cap_iter_end(src);
+}
 
+int ast_translate_init(void)
+{
+	int res = 0;
+	ast_rwlock_init(&tablelock);
+	res = matrix_resize(1);
+	res |= ast_cli_register_multiple(cli_translate, ARRAY_LEN(cli_translate));
 	return res;
 }
diff --git a/main/udptl.c b/main/udptl.c
index 1845ca8823c59047130adb4d5e85cdb8f6350dfd..f5abbb900bd8145ef964d73f1b38606f27a9840e 100644
--- a/main/udptl.c
+++ b/main/udptl.c
@@ -379,7 +379,7 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 					/* Decode the secondary IFP packet */
 					//fprintf(stderr, "Secondary %d, len %d\n", seq_no - i, lengths[i - 1]);
 					s->f[ifp_no].frametype = AST_FRAME_MODEM;
-					s->f[ifp_no].subclass.codec = AST_MODEM_T38;
+					s->f[ifp_no].subclass.integer = AST_MODEM_T38;
 
 					s->f[ifp_no].mallocd = 0;
 					s->f[ifp_no].seqno = seq_no - i;
@@ -481,7 +481,7 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 			if (repaired[l]) {
 				//fprintf(stderr, "Fixed packet %d, len %d\n", j, l);
 				s->f[ifp_no].frametype = AST_FRAME_MODEM;
-				s->f[ifp_no].subclass.codec = AST_MODEM_T38;
+				s->f[ifp_no].subclass.integer = AST_MODEM_T38;
 			
 				s->f[ifp_no].mallocd = 0;
 				s->f[ifp_no].seqno = j;
@@ -502,7 +502,7 @@ static int udptl_rx_packet(struct ast_udptl *s, uint8_t *buf, unsigned int len)
 	if (seq_no >= s->rx_seq_no) {
 		/* Decode the primary IFP packet */
 		s->f[ifp_no].frametype = AST_FRAME_MODEM;
-		s->f[ifp_no].subclass.codec = AST_MODEM_T38;
+		s->f[ifp_no].subclass.integer = AST_MODEM_T38;
 		
 		s->f[ifp_no].mallocd = 0;
 		s->f[ifp_no].seqno = seq_no;
@@ -1057,7 +1057,7 @@ int ast_udptl_write(struct ast_udptl *s, struct ast_frame *f)
 		return 0;
 	
 	if ((f->frametype != AST_FRAME_MODEM) ||
-	    (f->subclass.codec != AST_MODEM_T38)) {
+	    (f->subclass.integer != AST_MODEM_T38)) {
 		ast_log(LOG_WARNING, "(%s): UDPTL can only send T.38 data.\n",
 			LOG_TAG(s));
 		return -1;
diff --git a/pbx/pbx_spool.c b/pbx/pbx_spool.c
index d285af54bb20e1cc53a02a76b1fc7ad71a7a0eb2..bc832309b872c74e5cd80ead0b3421329c868498 100644
--- a/pbx/pbx_spool.c
+++ b/pbx/pbx_spool.c
@@ -74,7 +74,7 @@ struct outgoing {
 	int retrytime;                            /*!< How long to wait between retries (in seconds) */
 	int waittime;                             /*!< How long to wait for an answer */
 	long callingpid;                          /*!< PID which is currently calling */
-	format_t format;                          /*!< Formats (codecs) for this call */
+	struct ast_format_cap *capabilities;                 /*!< Formats (codecs) for this call */
 	AST_DECLARE_STRING_FIELDS (
 		AST_STRING_FIELD(fn);                 /*!< File name of call file */
 		AST_STRING_FIELD(tech);               /*!< Which channel technology to use for outgoing call */
@@ -99,10 +99,16 @@ static void queue_file(const char *filename, time_t when);
 
 static int init_outgoing(struct outgoing *o)
 {
+	struct ast_format tmpfmt;
 	o->priority = 1;
 	o->retrytime = 300;
 	o->waittime = 45;
-	o->format = AST_FORMAT_SLINEAR;
+
+	if (!(o->capabilities = ast_format_cap_alloc_nolock())) {
+		return -1;
+	}
+	ast_format_cap_add(o->capabilities, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+
 	ast_set_flag(&o->options, SPOOL_FLAG_ALWAYS_DELETE);
 	if (ast_string_field_init(o, 128)) {
 		return -1;
@@ -116,6 +122,7 @@ static void free_outgoing(struct outgoing *o)
 		ast_variables_destroy(o->vars);
 	}
 	ast_string_field_free_memory(o);
+	o->capabilities = ast_format_cap_destroy(o->capabilities);
 	ast_free(o);
 }
 
@@ -189,7 +196,7 @@ static int apply_outgoing(struct outgoing *o, const char *fn, FILE *f)
 						o->maxretries = 0;
 					}
 				} else if (!strcasecmp(buf, "codecs")) {
-					ast_parse_allow_disallow(NULL, &o->format, c, 1);
+					ast_parse_allow_disallow(NULL, o->capabilities, c, 1);
 				} else if (!strcasecmp(buf, "context")) {
 					ast_string_field_set(o, context, c);
 				} else if (!strcasecmp(buf, "extension")) {
@@ -338,11 +345,11 @@ static void *attempt_thread(void *data)
 	int res, reason;
 	if (!ast_strlen_zero(o->app)) {
 		ast_verb(3, "Attempting call on %s/%s for application %s(%s) (Retry %d)\n", o->tech, o->dest, o->app, o->data, o->retries);
-		res = ast_pbx_outgoing_app(o->tech, o->format, (void *) o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
+		res = ast_pbx_outgoing_app(o->tech, o->capabilities, (void *) o->dest, o->waittime * 1000, o->app, o->data, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
 		o->vars = NULL;
 	} else {
 		ast_verb(3, "Attempting call on %s/%s for %s@%s:%d (Retry %d)\n", o->tech, o->dest, o->exten, o->context,o->priority, o->retries);
-		res = ast_pbx_outgoing_exten(o->tech, o->format, (void *) o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
+		res = ast_pbx_outgoing_exten(o->tech, o->capabilities, (void *) o->dest, o->waittime * 1000, o->context, o->exten, o->priority, &reason, 2 /* wait to finish */, o->cid_num, o->cid_name, o->vars, o->account, NULL);
 		o->vars = NULL;
 	}
 	if (res) {
diff --git a/res/res_adsi.c b/res/res_adsi.c
index 226105d87b29f5ab51f4646d108eb2a5d0133761..0a1f623a5af31966c57fdddce80d784d3c6c11b9 100644
--- a/res/res_adsi.c
+++ b/res/res_adsi.c
@@ -69,7 +69,7 @@ static char speeddial[ADSI_MAX_SPEED_DIAL][3][SPEEDDIAL_MAX_LEN];
 
 static int alignment = 0;
 
-static int adsi_generate(unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, format_t codec)
+static int adsi_generate(unsigned char *buf, int msgtype, unsigned char *msg, int msglen, int msgnum, int last, struct ast_format *codec)
 {
 	int sum, x, bytes = 0;
 	/* Initial carrier (imaginary) */
@@ -139,7 +139,7 @@ static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int l
 			*remain = *remain - amt;
 		}
 		outf.frametype = AST_FRAME_VOICE;
-		outf.subclass.codec = AST_FORMAT_ULAW;
+		ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
 		outf.data.ptr = buf;
 		outf.datalen = amt;
 		outf.samples = amt;
@@ -170,7 +170,7 @@ static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int l
 			continue;
 		}
 
-		if (inf->subclass.codec != AST_FORMAT_ULAW) {
+		if (inf->subclass.format.id != AST_FORMAT_ULAW) {
 			ast_log(LOG_WARNING, "Channel not in ulaw?\n");
 			ast_frfree(inf);
 			return -1;
@@ -182,7 +182,7 @@ static int adsi_careful_send(struct ast_channel *chan, unsigned char *buf, int l
 			*remain = inf->datalen - amt;
 		}
 		outf.frametype = AST_FRAME_VOICE;
-		outf.subclass.codec = AST_FORMAT_ULAW;
+		ast_format_set(&outf.subclass.format, AST_FORMAT_ULAW, 0);
 		outf.data.ptr = buf;
 		outf.datalen = amt;
 		outf.samples = amt;
@@ -214,9 +214,11 @@ static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **ms
 	}
 
 	while (retries < maxretries) {
+		struct ast_format tmpfmt;
 		if (!(chan->adsicpe & ADSI_FLAG_DATAMODE)) {
 			/* Generate CAS (no SAS) */
-			ast_gen_cas(buf, 0, 680, AST_FORMAT_ULAW);
+			ast_format_set(&tmpfmt, AST_FORMAT_ULAW, 0);
+			ast_gen_cas(buf, 0, 680, &tmpfmt);
 
 			/* Send CAS */
 			if (adsi_careful_send(chan, buf, 680, NULL)) {
@@ -275,7 +277,7 @@ static int __adsi_transmit_messages(struct ast_channel *chan, unsigned char **ms
 		def= ast_channel_defer_dtmf(chan);
 #endif
 		while ((x < 6) && msg[x]) {
-			if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], AST_FORMAT_ULAW)) < 0) {
+			if ((res = adsi_generate(buf + pos, msgtype[x], msg[x], msglen[x], x+1 - start, (x == 5) || !msg[x+1], ast_format_set(&tmpfmt, AST_FORMAT_ULAW,0))) < 0) {
 				ast_log(LOG_WARNING, "Failed to generate ADSI message %d on channel %s\n", x + 1, chan->name);
 				return -1;
 			}
@@ -361,7 +363,12 @@ int AST_OPTIONAL_API_NAME(ast_adsi_end_download)(struct ast_channel *chan)
 int AST_OPTIONAL_API_NAME(ast_adsi_transmit_message_full)(struct ast_channel *chan, unsigned char *msg, int msglen, int msgtype, int dowait)
 {
 	unsigned char *msgs[5] = { NULL, NULL, NULL, NULL, NULL };
-	int msglens[5], msgtypes[5], newdatamode = (chan->adsicpe & ADSI_FLAG_DATAMODE), res, x, writeformat = chan->writeformat, readformat = chan->readformat, waitforswitch = 0;
+	int msglens[5], msgtypes[5], newdatamode = (chan->adsicpe & ADSI_FLAG_DATAMODE), res, x, waitforswitch = 0;
+	struct ast_format writeformat;
+	struct ast_format readformat;
+
+	ast_format_copy(&writeformat, &chan->writeformat);
+	ast_format_copy(&readformat, &chan->readformat);
 
 	for (x = 0; x < msglen; x += (msg[x+1]+2)) {
 		if (msg[x] == ADSI_SWITCH_TO_DATA) {
@@ -388,16 +395,16 @@ int AST_OPTIONAL_API_NAME(ast_adsi_transmit_message_full)(struct ast_channel *ch
 
 	ast_stopstream(chan);
 
-	if (ast_set_write_format(chan, AST_FORMAT_ULAW)) {
+	if (ast_set_write_format_by_id(chan, AST_FORMAT_ULAW)) {
 		ast_log(LOG_WARNING, "Unable to set write format to ULAW\n");
 		return -1;
 	}
 
-	if (ast_set_read_format(chan, AST_FORMAT_ULAW)) {
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_ULAW)) {
 		ast_log(LOG_WARNING, "Unable to set read format to ULAW\n");
-		if (writeformat) {
-			if (ast_set_write_format(chan, writeformat)) {
-				ast_log(LOG_WARNING, "Unable to restore write format to %d\n", writeformat);
+		if (writeformat.id) {
+			if (ast_set_write_format(chan, &writeformat)) {
+				ast_log(LOG_WARNING, "Unable to restore write format to %s\n", ast_getformatname(&writeformat));
 			}
 		}
 		return -1;
@@ -416,11 +423,11 @@ int AST_OPTIONAL_API_NAME(ast_adsi_transmit_message_full)(struct ast_channel *ch
 		chan->adsicpe = (chan->adsicpe & ~ADSI_FLAG_DATAMODE) | newdatamode;
 	}
 
-	if (writeformat) {
-		ast_set_write_format(chan, writeformat);
+	if (writeformat.id) {
+		ast_set_write_format(chan, &writeformat);
 	}
-	if (readformat) {
-		ast_set_read_format(chan, readformat);
+	if (readformat.id) {
+		ast_set_read_format(chan, &readformat);
 	}
 
 	if (!res) {
diff --git a/res/res_agi.c b/res/res_agi.c
index 7dc2d20c9c581680c07e8397d9751ac661aad468..09cdc396691296bcc36bd9f1e4b0909ce8d3033e 100644
--- a/res/res_agi.c
+++ b/res/res_agi.c
@@ -2146,7 +2146,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const
 	int silence = 0;                /* amount of silence to allow */
 	int gotsilence = 0;             /* did we timeout for silence? */
 	char *silencestr = NULL;
-	int rfmt = 0;
+	struct ast_format rfmt;
+	ast_format_clear(&rfmt);
 
 	/* XXX EAGI FIXME XXX */
 
@@ -2176,8 +2177,8 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const
 	}
 
 	if (silence > 0) {
-		rfmt = chan->readformat;
-		res = ast_set_read_format(chan, AST_FORMAT_SLINEAR);
+		ast_format_copy(&rfmt, &chan->readformat);
+		res = ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR);
 		if (res < 0) {
 			ast_log(LOG_WARNING, "Unable to set to linear mode, giving up\n");
 			return -1;
@@ -2299,7 +2300,7 @@ static int handle_recordfile(struct ast_channel *chan, AGI *agi, int argc, const
 	}
 
 	if (silence > 0) {
-		res = ast_set_read_format(chan, rfmt);
+		res = ast_set_read_format(chan, &rfmt);
 		if (res)
 			ast_log(LOG_WARNING, "Unable to restore read format on '%s'\n", chan->name);
 		ast_dsp_free(sildet);
@@ -2650,16 +2651,25 @@ static int handle_setmusic(struct ast_channel *chan, AGI *agi, int argc, const c
 
 static int handle_speechcreate(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[])
 {
+	struct ast_format_cap *cap;
+	struct ast_format tmpfmt;
+
 	/* If a structure already exists, return an error */
-        if (agi->speech) {
+	if (agi->speech) {
 		ast_agi_send(agi->fd, chan, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
 
-	if ((agi->speech = ast_speech_new(argv[2], AST_FORMAT_SLINEAR)))
+	if (!(cap = ast_format_cap_alloc_nolock())) {
+		return RESULT_FAILURE;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	if ((agi->speech = ast_speech_new(argv[2], cap))) {
 		ast_agi_send(agi->fd, chan, "200 result=1\n");
-	else
+	} else {
 		ast_agi_send(agi->fd, chan, "200 result=0\n");
+	}
+	cap = ast_format_cap_destroy(cap);
 
 	return RESULT_SUCCESS;
 }
@@ -2791,7 +2801,8 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
 	struct ast_speech *speech = agi->speech;
 	const char *prompt;
 	char dtmf = 0, tmp[4096] = "", *buf = tmp;
-	int timeout = 0, offset = 0, old_read_format = 0, res = 0, i = 0;
+	int timeout = 0, offset = 0, res = 0, i = 0;
+	struct ast_format old_read_format;
 	long current_offset = 0;
 	const char *reason = NULL;
 	struct ast_frame *fr = NULL;
@@ -2815,8 +2826,8 @@ static int handle_speechrecognize(struct ast_channel *chan, AGI *agi, int argc,
 		offset = atoi(argv[4]);
 
 	/* We want frames coming in signed linear */
-	old_read_format = chan->readformat;
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
+	ast_format_copy(&old_read_format, &chan->readformat);
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_agi_send(agi->fd, chan, "200 result=0\n");
 		return RESULT_SUCCESS;
 	}
@@ -3759,21 +3770,22 @@ static int agi_exec(struct ast_channel *chan, const char *data)
 
 static int eagi_exec(struct ast_channel *chan, const char *data)
 {
-	int readformat, res;
+	int res;
+	struct ast_format readformat;
 
 	if (ast_check_hangup(chan)) {
 		ast_log(LOG_ERROR, "EAGI cannot be run on a dead/hungup channel, please use AGI.\n");
 		return 0;
 	}
-	readformat = chan->readformat;
-	if (ast_set_read_format(chan, AST_FORMAT_SLINEAR)) {
+	ast_format_copy(&readformat, &chan->readformat);
+	if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR)) {
 		ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", chan->name);
 		return -1;
 	}
 	res = agi_exec_full(chan, data, 1, 0);
 	if (!res) {
-		if (ast_set_read_format(chan, readformat)) {
-			ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(readformat));
+		if (ast_set_read_format(chan, &readformat)) {
+			ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n", chan->name, ast_getformatname(&readformat));
 		}
 	}
 	return res;
diff --git a/res/res_calendar.c b/res/res_calendar.c
index d5c716025be24d991226888c61f8ad2492601a2b..af81c183f87acab4abd81334c7b346b06fb640c6 100644
--- a/res/res_calendar.c
+++ b/res/res_calendar.c
@@ -702,8 +702,12 @@ static void *do_notify(void *data)
 	}
 
 	chan->tech = &null_tech;
-	chan->nativeformats = chan->writeformat = chan->rawwriteformat =
-		chan->readformat = chan->rawreadformat = AST_FORMAT_SLINEAR;
+	ast_format_set(&chan->writeformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&chan->readformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&chan->rawwriteformat, AST_FORMAT_SLINEAR, 0);
+	ast_format_set(&chan->rawreadformat, AST_FORMAT_SLINEAR, 0);
+	/* clear native formats and set to slinear. write format is signlear so just use that to set it */
+	ast_format_cap_set(chan->nativeformats, &chan->writeformat);
 
 	if (!(datastore = ast_datastore_alloc(&event_notification_datastore, NULL))) {
 		ast_log(LOG_ERROR, "Could not allocate datastore, notification not being sent!\n");
diff --git a/res/res_clioriginate.c b/res/res_clioriginate.c
index 01cf9f7b75b2218ccd03acf0b032d7f0b87eeb4b..f244c165dc492733cb5d8081b101d1b0bd3bda28 100644
--- a/res/res_clioriginate.c
+++ b/res/res_clioriginate.c
@@ -52,6 +52,8 @@ static char *orig_app(int fd, const char *chan, const char *app, const char *app
 	char *chantech;
 	char *chandata;
 	int reason = 0;
+	struct ast_format_cap *cap;
+	struct ast_format tmpfmt;
 
 	if (ast_strlen_zero(app))
 		return CLI_SHOWUSAGE;
@@ -64,7 +66,12 @@ static char *orig_app(int fd, const char *chan, const char *app, const char *app
 		return CLI_SHOWUSAGE;
 	}
 
-	ast_pbx_outgoing_app(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
+	if (!(cap = ast_format_cap_alloc_nolock())) {
+		return CLI_FAILURE;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	ast_pbx_outgoing_app(chantech, cap, chandata, TIMEOUT * 1000, app, appdata, &reason, 0, NULL, NULL, NULL, NULL, NULL);
+	cap = ast_format_cap_destroy(cap);
 
 	return CLI_SUCCESS;
 }
@@ -84,6 +91,8 @@ static char *orig_exten(int fd, const char *chan, const char *data)
 	char *exten = NULL;
 	char *context = NULL;
 	int reason = 0;
+	struct ast_format_cap *cap;
+	struct ast_format tmpfmt;
 
 	chandata = ast_strdupa(chan);
 
@@ -102,8 +111,12 @@ static char *orig_exten(int fd, const char *chan, const char *data)
 		exten = "s";
 	if (ast_strlen_zero(context))
 		context = "default";
-
-	ast_pbx_outgoing_exten(chantech, AST_FORMAT_SLINEAR, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL);
+	if (!(cap = ast_format_cap_alloc_nolock())) {
+		return CLI_FAILURE;
+	}
+	ast_format_cap_add(cap, ast_format_set(&tmpfmt, AST_FORMAT_SLINEAR, 0));
+	ast_pbx_outgoing_exten(chantech, cap, chandata, TIMEOUT * 1000, context, exten, 1, &reason, 0, NULL, NULL, NULL, NULL, NULL);
+	cap = ast_format_cap_destroy(cap);
 
 	return CLI_SUCCESS;
 }
diff --git a/res/res_fax.c b/res/res_fax.c
index 2ec7d2e3a2cb74b226728c1ee8b1c1c3237b9bb5..1191658ca0fe1594d9f11bf22afef4fd2a895b75 100644
--- a/res/res_fax.c
+++ b/res/res_fax.c
@@ -1095,8 +1095,11 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 	struct ast_fax_session *fax = NULL;
 	struct ast_frame *frame = NULL;
 	struct ast_channel *c = chan;
-	unsigned int orig_write_format = 0, orig_read_format = 0;
+	struct ast_format orig_write_format;
+	struct ast_format orig_read_format;
 
+	ast_format_clear(&orig_write_format);
+	ast_format_clear(&orig_read_format);
 	chancount = 1;
 
 	/* create the FAX session */
@@ -1121,9 +1124,9 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 
 	if (details->caps & AST_FAX_TECH_AUDIO) {
 		expected_frametype = AST_FRAME_VOICE;;
-		expected_framesubclass.codec = AST_FORMAT_SLINEAR;
-		orig_write_format = chan->writeformat;
-		if (ast_set_write_format(chan, AST_FORMAT_SLINEAR) < 0) {
+		ast_format_set(&expected_framesubclass.format, AST_FORMAT_SLINEAR, 0);
+		ast_format_copy(&orig_write_format, &chan->writeformat);
+		if (ast_set_write_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 			ast_log(LOG_ERROR, "channel '%s' failed to set write format to signed linear'.\n", chan->name);
  			ao2_lock(faxregistry.container);
  			ao2_unlink(faxregistry.container, fax);
@@ -1132,8 +1135,8 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 			ast_channel_unlock(chan);
 			return -1;
 		}
-		orig_read_format = chan->readformat;
-		if (ast_set_read_format(chan, AST_FORMAT_SLINEAR) < 0) {
+		ast_format_copy(&orig_read_format, &chan->readformat);
+		if (ast_set_read_format_by_id(chan, AST_FORMAT_SLINEAR) < 0) {
 			ast_log(LOG_ERROR, "channel '%s' failed to set read format to signed linear.\n", chan->name);
  			ao2_lock(faxregistry.container);
  			ao2_unlink(faxregistry.container, fax);
@@ -1151,7 +1154,7 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 		}
 	} else {
 		expected_frametype = AST_FRAME_MODEM;
-		expected_framesubclass.codec = AST_MODEM_T38;
+		expected_framesubclass.integer = AST_MODEM_T38;
 	}
 
 	if (fax->debug_info) {
@@ -1226,7 +1229,7 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 					fax->tech->switch_to_t38(fax);
 					details->caps &= ~AST_FAX_TECH_AUDIO;
 					expected_frametype = AST_FRAME_MODEM;
-					expected_framesubclass.codec = AST_MODEM_T38;
+					expected_framesubclass.integer = AST_MODEM_T38;
 					if (fax->smoother) {
 						ast_smoother_free(fax->smoother);
 						fax->smoother = NULL;
@@ -1327,11 +1330,11 @@ static int generic_fax_exec(struct ast_channel *chan, struct ast_fax_session_det
 	 * restore them now
 	 */
 	if (chancount) {
-		if (orig_read_format) {
-			ast_set_read_format(chan, orig_read_format);
+		if (orig_read_format.id) {
+			ast_set_read_format(chan, &orig_read_format);
 		}
-		if (orig_write_format) {
-			ast_set_write_format(chan, orig_write_format);
+		if (orig_write_format.id) {
+			ast_set_write_format(chan, &orig_write_format);
 		}
 	}
 
diff --git a/res/res_fax_spandsp.c b/res/res_fax_spandsp.c
index 6b2f103a7464b45580ffa44c872662321ebe83ac..21b4b496c016a422bf1bcacb4f19af998f1a62f4 100644
--- a/res/res_fax_spandsp.c
+++ b/res/res_fax_spandsp.c
@@ -492,11 +492,10 @@ static struct ast_frame *spandsp_fax_read(struct ast_fax_session *s)
 
 	struct ast_frame fax_frame = {
 		.frametype = AST_FRAME_VOICE,
-		.subclass.codec = AST_FORMAT_SLINEAR,
 		.src = "res_fax_spandsp_g711",
 	};
-
 	struct ast_frame *f = &fax_frame;
+	ast_format_set(&fax_frame.subclass.format, AST_FORMAT_SLINEAR, 0);
 
 	ast_timer_ack(p->timer, 1);
 
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c
index 45280bf746f12f3b6e6602e487aeb8d61ff6090a..1d7aeadb55835195793516614eb2aa2ec9ac734e 100644
--- a/res/res_musiconhold.c
+++ b/res/res_musiconhold.c
@@ -152,7 +152,7 @@ static int respawn_time = 20;
 struct moh_files_state {
 	struct mohclass *class;
 	char name[MAX_MUSICCLASS];
-	format_t origwfmt;
+	struct ast_format origwfmt;
 	int samples;
 	int sample_queue;
 	int pos;
@@ -188,7 +188,7 @@ struct mohclass {
 	int total_files;
 	unsigned int flags;
 	/*! The format from the MOH source, not applicable to "files" mode */
-	format_t format;
+	struct ast_format format;
 	/*! The pid of the external application delivering MOH */
 	int pid;
 	time_t start;
@@ -206,7 +206,7 @@ struct mohclass {
 
 struct mohdata {
 	int pipe[2];
-	format_t origwfmt;
+	struct ast_format origwfmt;
 	struct mohclass *parent;
 	struct ast_frame f;
 	AST_LIST_ENTRY(mohdata) list;
@@ -267,8 +267,8 @@ static void moh_files_release(struct ast_channel *chan, void *data)
 		ast_verbose(VERBOSE_PREFIX_3 "Stopped music on hold on %s\n", chan->name);
 	}
 
-	if (state->origwfmt && ast_set_write_format(chan, state->origwfmt)) {
-		ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%s'\n", chan->name, ast_getformatname(state->origwfmt));
+	if (state->origwfmt.id && ast_set_write_format(chan, &state->origwfmt)) {
+		ast_log(LOG_WARNING, "Unable to restore channel '%s' to format '%s'\n", chan->name, ast_getformatname(&state->origwfmt));
 	}
 
 	state->save_pos = state->pos;
@@ -666,7 +666,7 @@ static void *monmp3thread(void *data)
 		if ((strncasecmp(class->dir, "http://", 7) && strcasecmp(class->dir, "nodir")) && AST_LIST_EMPTY(&class->members))
 			continue;
 		/* Read mp3 audio */
-		len = ast_codec_get_len(class->format, res);
+		len = ast_codec_get_len(&class->format, res);
 
 		if ((res2 = read(class->srcfd, sbuf, len)) != len) {
 			if (!res2) {
@@ -869,7 +869,7 @@ static struct mohdata *mohalloc(struct mohclass *cl)
 	fcntl(moh->pipe[1], F_SETFL, flags | O_NONBLOCK);
 
 	moh->f.frametype = AST_FRAME_VOICE;
-	moh->f.subclass.codec = cl->format;
+	ast_format_copy(&moh->f.subclass.format, &cl->format);
 	moh->f.offset = AST_FRIENDLY_OFFSET;
 
 	moh->parent = mohclass_ref(cl, "Reffing music class for mohdata parent");
@@ -885,7 +885,7 @@ static void moh_release(struct ast_channel *chan, void *data)
 {
 	struct mohdata *moh = data;
 	struct mohclass *class = moh->parent;
-	format_t oldwfmt;
+	struct ast_format oldwfmt;
 
 	ao2_lock(class);
 	AST_LIST_REMOVE(&moh->parent->members, moh, list);	
@@ -894,16 +894,16 @@ static void moh_release(struct ast_channel *chan, void *data)
 	close(moh->pipe[0]);
 	close(moh->pipe[1]);
 
-	oldwfmt = moh->origwfmt;
+	ast_format_copy(&oldwfmt, &moh->origwfmt);
 
 	moh->parent = class = mohclass_unref(class, "unreffing moh->parent upon deactivation of generator");
 
 	ast_free(moh);
 
 	if (chan) {
-		if (oldwfmt && ast_set_write_format(chan, oldwfmt)) {
+		if (oldwfmt.id && ast_set_write_format(chan, &oldwfmt)) {
 			ast_log(LOG_WARNING, "Unable to restore channel '%s' to format %s\n",
-					chan->name, ast_getformatname(oldwfmt));
+					chan->name, ast_getformatname(&oldwfmt));
 		}
 
 		ast_verb(3, "Stopped music on hold on %s\n", chan->name);
@@ -930,8 +930,8 @@ static void *moh_alloc(struct ast_channel *chan, void *params)
 
 	if ((res = mohalloc(class))) {
 		res->origwfmt = chan->writeformat;
-		if (ast_set_write_format(chan, class->format)) {
-			ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(class->format));
+		if (ast_set_write_format(chan, &class->format)) {
+			ast_log(LOG_WARNING, "Unable to set channel '%s' to format '%s'\n", chan->name, ast_codec2str(&class->format));
 			moh_release(NULL, res);
 			res = NULL;
 		}
@@ -946,7 +946,7 @@ static int moh_generate(struct ast_channel *chan, void *data, int len, int sampl
 	short buf[1280 + AST_FRIENDLY_OFFSET / 2];
 	int res;
 
-	len = ast_codec_get_len(moh->parent->format, samples);
+	len = ast_codec_get_len(&moh->parent->format, samples);
 
 	if (len > sizeof(buf) - AST_FRIENDLY_OFFSET) {
 		ast_log(LOG_WARNING, "Only doing %d of %d requested bytes on %s\n", (int)sizeof(buf), len, chan->name);
@@ -1276,7 +1276,7 @@ static struct mohclass *_moh_class_malloc(const char *file, int line, const char
 			ao2_alloc(sizeof(*class), moh_class_destructor)
 #endif
 		)) {
-		class->format = AST_FORMAT_SLINEAR;
+		ast_format_set(&class->format, AST_FORMAT_SLINEAR, 0);
 		class->srcfd = -1;
 	}
 
@@ -1354,10 +1354,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con
 				else if (!strcasecmp(tmp->name, "sort") && !strcasecmp(tmp->value, "alpha")) 
 					ast_set_flag(mohclass, MOH_SORTALPHA);
 				else if (!strcasecmp(tmp->name, "format")) {
-					mohclass->format = ast_getformatbyname(tmp->value);
-					if (!mohclass->format) {
+					ast_getformatbyname(tmp->value, &mohclass->format);
+					if (!mohclass->format.id) {
 						ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", tmp->value);
-						mohclass->format = AST_FORMAT_SLINEAR;
+						ast_format_set(&mohclass->format, AST_FORMAT_SLINEAR, 0);
 					}
 				}
 			}
@@ -1683,10 +1683,10 @@ static int load_moh_classes(int reload)
 			else if (!strcasecmp(var->name, "sort") && !strcasecmp(var->value, "alpha")) 
 				ast_set_flag(class, MOH_SORTALPHA);
 			else if (!strcasecmp(var->name, "format")) {
-				class->format = ast_getformatbyname(var->value);
-				if (!class->format) {
+				ast_getformatbyname(var->value, &class->format);
+				if (!class->format.id) {
 					ast_log(LOG_WARNING, "Unknown format '%s' -- defaulting to SLIN\n", var->value);
-					class->format = AST_FORMAT_SLINEAR;
+					ast_format_set(&class->format, AST_FORMAT_SLINEAR, 0);
 				}
 			}
 		}
@@ -1819,7 +1819,7 @@ static char *handle_cli_moh_show_classes(struct ast_cli_entry *e, int cmd, struc
 			ast_cli(a->fd, "\tApplication: %s\n", S_OR(class->args, "<none>"));
 		}
 		if (strcasecmp(class->mode, "files")) {
-			ast_cli(a->fd, "\tFormat: %s\n", ast_getformatname(class->format));
+			ast_cli(a->fd, "\tFormat: %s\n", ast_getformatname(&class->format));
 		}
 	}
 	ao2_iterator_destroy(&i);
diff --git a/res/res_rtp_asterisk.c b/res/res_rtp_asterisk.c
index 785b4040d8d1942249fd7ec5cf28ad15de336731..f91cdb117ae618a2ddc1b332440a51d277c0b338 100644
--- a/res/res_rtp_asterisk.c
+++ b/res/res_rtp_asterisk.c
@@ -130,8 +130,8 @@ struct ast_rtp {
 	unsigned int cycles;            /*!< Shifted count of sequence number cycles */
 	double rxjitter;                /*!< Interarrival jitter at the moment */
 	double rxtransit;               /*!< Relative transit time for previous packet */
-	format_t lasttxformat;
-	format_t lastrxformat;
+	struct ast_format lasttxformat;
+	struct ast_format lastrxformat;
 
 	int rtptimeout;			/*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
 	int rtpholdtimeout;		/*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
@@ -368,9 +368,9 @@ static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size,
 	return __rtp_sendto(instance, buf, size, flags, sa, 0);
 }
 
-static int rtp_get_rate(format_t subclass)
+static int rtp_get_rate(struct ast_format *format)
 {
-	return (subclass == AST_FORMAT_G722) ? 8000 : ast_format_rate(subclass);
+	return (format->id == AST_FORMAT_G722) ? 8000 : ast_format_rate(format);
 }
 
 static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
@@ -560,7 +560,7 @@ static int ast_rtp_dtmf_begin(struct ast_rtp_instance *instance, char digit)
 	}
 
 	/* Grab the payload that they expect the RFC2833 packet to be received in */
-	payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 0, AST_RTP_DTMF);
+	payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 0, NULL, AST_RTP_DTMF);
 
 	rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
 	rtp->send_duration = 160;
@@ -675,7 +675,7 @@ static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, cha
 
 	rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
 
-	if (duration > 0 && (measured_samples = duration * rtp_get_rate(rtp->f.subclass.codec) / 1000) > rtp->send_duration) {
+	if (duration > 0 && (measured_samples = duration * rtp_get_rate(&rtp->f.subclass.format) / 1000) > rtp->send_duration) {
 		ast_debug(2, "Adjusting final end duration from %u to %u\n", rtp->send_duration, measured_samples);
 		rtp->send_duration = measured_samples;
 	}
@@ -1037,9 +1037,9 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
 	int pred, mark = 0;
 	unsigned int ms = calc_txstamp(rtp, &frame->delivery);
 	struct ast_sockaddr remote_address = { {0,} };
-	int rate = rtp_get_rate(frame->subclass.codec) / 1000;
+	int rate = rtp_get_rate(&frame->subclass.format) / 1000;
 
-	if (frame->subclass.codec == AST_FORMAT_G722) {
+	if (frame->subclass.format.id == AST_FORMAT_G722) {
 		frame->samples /= 2;
 	}
 
@@ -1063,7 +1063,7 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
 			}
 		}
 	} else if (frame->frametype == AST_FRAME_VIDEO) {
-		mark = frame->subclass.codec & 0x1;
+		mark = ast_format_get_video_mark(&frame->subclass.format);
 		pred = rtp->lastovidtimestamp + frame->samples;
 		/* Re-calculate last TS */
 		rtp->lastts = rtp->lastts + ms * 90;
@@ -1195,7 +1195,8 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
 {
 	struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
 	struct ast_sockaddr remote_address = { {0,} };
-	format_t codec, subclass;
+	struct ast_format subclass;
+	int codec;
 
 	ast_rtp_instance_get_remote_address(instance, &remote_address);
 
@@ -1225,19 +1226,17 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
 	}
 
 	/* Grab the subclass and look up the payload we are going to use */
-	subclass = frame->subclass.codec;
-	if (frame->frametype == AST_FRAME_VIDEO) {
-		subclass &= ~0x1LL;
-	}
-	if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, subclass)) < 0) {
-		ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(frame->subclass.codec));
+	ast_format_copy(&subclass, &frame->subclass.format);
+	if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, &subclass, 0)) < 0) {
+		ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(&frame->subclass.format));
 		return -1;
 	}
 
 	/* Oh dear, if the format changed we will have to set up a new smoother */
-	if (rtp->lasttxformat != subclass) {
-		ast_debug(1, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
+	if (ast_format_cmp(&rtp->lasttxformat, &subclass) == AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_debug(1, "Ooh, format changed from %s to %s\n", ast_getformatname(&rtp->lasttxformat), ast_getformatname(&subclass));
 		rtp->lasttxformat = subclass;
+		ast_format_copy(&rtp->lasttxformat, &subclass);
 		if (rtp->smoother) {
 			ast_smoother_free(rtp->smoother);
 			rtp->smoother = NULL;
@@ -1246,9 +1245,9 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
 
 	/* If no smoother is present see if we have to set one up */
 	if (!rtp->smoother) {
-		struct ast_format_list fmt = ast_codec_pref_getsize(&ast_rtp_instance_get_codecs(instance)->pref, subclass);
+		struct ast_format_list fmt = ast_codec_pref_getsize(&ast_rtp_instance_get_codecs(instance)->pref, &subclass);
 
-		switch (subclass) {
+		switch (subclass.id) {
 		case AST_FORMAT_SPEEX:
 		case AST_FORMAT_SPEEX16:
 		case AST_FORMAT_G723_1:
@@ -1261,13 +1260,13 @@ static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *fr
 		default:
 			if (fmt.inc_ms) {
 				if (!(rtp->smoother = ast_smoother_new((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_getformatname(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_getformatname(&subclass), 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: %s ms: %d len: %d\n", ast_getformatname(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_getformatname(&subclass), fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
 			}
 		}
 	}
@@ -1315,7 +1314,7 @@ static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int t
 	double d;
 	double dtv;
 	double prog;
-	int rate = rtp_get_rate(rtp->f.subclass.codec);
+	int rate = rtp_get_rate(&rtp->f.subclass.format);
 
 	double normdev_rxjitter_current;
 	if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
@@ -1478,7 +1477,7 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 			if ((rtp->lastevent != seqno) && rtp->resp) {
 				rtp->dtmf_duration = new_duration;
 				f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
-				f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), ast_tv(0, 0));
+				f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(&f->subclass.format)), ast_tv(0, 0));
 				rtp->resp = 0;
 				rtp->dtmf_duration = rtp->dtmf_timeout = 0;
 				AST_LIST_INSERT_TAIL(frames, f, frame_list);
@@ -1489,7 +1488,7 @@ static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned cha
 			if (rtp->resp && rtp->resp != resp) {
 				/* Another digit already began. End it */
 				f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
-				f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), ast_tv(0, 0));
+				f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(&f->subclass.format)), ast_tv(0, 0));
 				rtp->resp = 0;
 				rtp->dtmf_duration = rtp->dtmf_timeout = 0;
 				AST_LIST_INSERT_TAIL(frames, f, frame_list);
@@ -1586,10 +1585,10 @@ static struct ast_frame *process_dtmf_cisco(struct ast_rtp_instance *instance, u
 		}
 	} else if ((rtp->resp == resp) && !power) {
 		f = create_dtmf_frame(instance, AST_FRAME_DTMF_END, ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_DTMF_COMPENSATE));
-		f->samples = rtp->dtmfsamples * (rtp->lastrxformat ? (rtp_get_rate(rtp->lastrxformat) / 1000) : 8);
+		f->samples = rtp->dtmfsamples * (rtp->lastrxformat.id ? (rtp_get_rate(&rtp->lastrxformat) / 1000) : 8);
 		rtp->resp = 0;
 	} else if (rtp->resp == resp)
-		rtp->dtmfsamples += 20 * (rtp->lastrxformat ? (rtp_get_rate(rtp->lastrxformat) / 1000) : 8);
+		rtp->dtmfsamples += 20 * (rtp->lastrxformat.id ? (rtp_get_rate(&rtp->lastrxformat) / 1000) : 8);
 
 	rtp->dtmf_timeout = 0;
 
@@ -1604,7 +1603,7 @@ static struct ast_frame *process_cn_rfc3389(struct ast_rtp_instance *instance, u
 	   totally help us out becuase we don't have an engine to keep it going and we are not
 	   guaranteed to have it every 20ms or anything */
 	if (rtpdebug)
-		ast_debug(0, "- RTP 3389 Comfort noise event: Level %" PRId64 " (len = %d)\n", rtp->lastrxformat, len);
+		ast_debug(0, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", (int) rtp->lastrxformat.id, len);
 
 	if (ast_test_flag(rtp, FLAG_3389_WARNING)) {
 		struct ast_sockaddr remote_address = { {0,} };
@@ -1924,10 +1923,11 @@ static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int
 	payload_type = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(instance), payload);
 
 	/* Otherwise adjust bridged payload to match */
-	bridged_payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance1), payload_type.asterisk_format, payload_type.code);
+	bridged_payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance1), payload_type.asterisk_format, &payload_type.format, payload_type.rtp_code);
 
 	/* 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 (!(ast_rtp_instance_get_codecs(instance1)->payloads[bridged_payload].code)) {
+	if (!(ast_rtp_instance_get_codecs(instance1)->payloads[bridged_payload].rtp_code) &&
+	!(ast_rtp_instance_get_codecs(instance1)->payloads[bridged_payload].asterisk_format)) {
 		return -1;
 	}
 
@@ -2176,15 +2176,15 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 	/* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
 	if (!payload.asterisk_format) {
 		struct ast_frame *f = NULL;
-		if (payload.code == AST_RTP_DTMF) {
+		if (payload.rtp_code == AST_RTP_DTMF) {
 			/* process_dtmf_rfc2833 may need to return multiple frames. We do this
 			 * by passing the pointer to the frame list to it so that the method
 			 * can append frames to the list as needed.
 			 */
 			process_dtmf_rfc2833(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark, &frames);
-		} else if (payload.code == AST_RTP_CISCO_DTMF) {
+		} else if (payload.rtp_code == AST_RTP_CISCO_DTMF) {
 			f = process_dtmf_cisco(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark);
-		} else if (payload.code == AST_RTP_CN) {
+		} else if (payload.rtp_code == AST_RTP_CN) {
 			f = process_cn_rfc3389(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark);
 		} else {
 			ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n",
@@ -2204,8 +2204,9 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		return &ast_null_frame;
 	}
 
-	rtp->lastrxformat = rtp->f.subclass.codec = payload.code;
-	rtp->f.frametype = (rtp->f.subclass.codec & AST_FORMAT_AUDIO_MASK) ? AST_FRAME_VOICE : (rtp->f.subclass.codec & AST_FORMAT_VIDEO_MASK) ? AST_FRAME_VIDEO : AST_FRAME_TEXT;
+	ast_format_copy(&rtp->lastrxformat, &payload.format);
+	ast_format_copy(&rtp->f.subclass.format, &payload.format);
+	rtp->f.frametype = (AST_FORMAT_GET_TYPE(rtp->f.subclass.format.id) == AST_FORMAT_TYPE_AUDIO) ? AST_FRAME_VOICE : (AST_FORMAT_GET_TYPE(rtp->f.subclass.format.id) == AST_FORMAT_TYPE_VIDEO) ? AST_FRAME_VIDEO : AST_FRAME_TEXT;
 
 	rtp->rxseqno = seqno;
 
@@ -2215,7 +2216,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		if (rtp->resp) {
 			struct ast_frame *f;
 			f = create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0);
-			f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(f->subclass.codec)), ast_tv(0, 0));
+			f->len = ast_tvdiff_ms(ast_samp2tv(rtp->dtmf_duration, rtp_get_rate(&f->subclass.format)), ast_tv(0, 0));
 			rtp->resp = 0;
 			rtp->dtmf_timeout = rtp->dtmf_duration = 0;
 			AST_LIST_INSERT_TAIL(&frames, f, frame_list);
@@ -2232,7 +2233,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 	rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
 	rtp->f.seqno = seqno;
 
-	if (rtp->f.subclass.codec == AST_FORMAT_T140 && (int)seqno - (prev_seqno+1) > 0 && (int)seqno - (prev_seqno+1) < 10) {
+	if (rtp->f.subclass.format.id == AST_FORMAT_T140 && (int)seqno - (prev_seqno+1) > 0 && (int)seqno - (prev_seqno+1) < 10) {
 		unsigned char *data = rtp->f.data.ptr;
 
 		memmove(rtp->f.data.ptr+3, rtp->f.data.ptr, rtp->f.datalen);
@@ -2242,7 +2243,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		*data = 0xBD;
 	}
 
-	if (rtp->f.subclass.codec == AST_FORMAT_T140RED) {
+	if (rtp->f.subclass.format.id == AST_FORMAT_T140RED) {
 		unsigned char *data = rtp->f.data.ptr;
 		unsigned char *header_end;
 		int num_generations;
@@ -2251,7 +2252,7 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		int diff =(int)seqno - (prev_seqno+1); /* if diff = 0, no drop*/
 		int x;
 
-		rtp->f.subclass.codec = AST_FORMAT_T140;
+		ast_format_set(&rtp->f.subclass.format, AST_FORMAT_T140, 0);
 		header_end = memchr(data, ((*data) & 0x7f), rtp->f.datalen);
 		if (header_end == NULL) {
 			return AST_LIST_FIRST(&frames) ? AST_LIST_FIRST(&frames) : &ast_null_frame;
@@ -2289,17 +2290,17 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		}
 	}
 
-	if (rtp->f.subclass.codec & AST_FORMAT_AUDIO_MASK) {
+	if (AST_FORMAT_GET_TYPE(rtp->f.subclass.format.id) == AST_FORMAT_TYPE_AUDIO) {
 		rtp->f.samples = ast_codec_get_samples(&rtp->f);
-		if ((rtp->f.subclass.codec == AST_FORMAT_SLINEAR) || (rtp->f.subclass.codec == AST_FORMAT_SLINEAR16)) {
+		if ((rtp->f.subclass.format.id == AST_FORMAT_SLINEAR) || (rtp->f.subclass.format.id == AST_FORMAT_SLINEAR16)) {
 			ast_frame_byteswap_be(&rtp->f);
 		}
 		calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
 		/* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
 		ast_set_flag(&rtp->f, AST_FRFLAG_HAS_TIMING_INFO);
-		rtp->f.ts = timestamp / (rtp_get_rate(rtp->f.subclass.codec) / 1000);
-		rtp->f.len = rtp->f.samples / ((ast_format_rate(rtp->f.subclass.codec) / 1000));
-	} else if (rtp->f.subclass.codec & AST_FORMAT_VIDEO_MASK) {
+		rtp->f.ts = timestamp / (rtp_get_rate(&rtp->f.subclass.format) / 1000);
+		rtp->f.len = rtp->f.samples / ((ast_format_rate(&rtp->f.subclass.format) / 1000));
+	} else if (AST_FORMAT_GET_TYPE(rtp->f.subclass.format.id) == AST_FORMAT_TYPE_VIDEO) {
 		/* Video -- samples is # of samples vs. 90000 */
 		if (!rtp->lastividtimestamp)
 			rtp->lastividtimestamp = timestamp;
@@ -2307,13 +2308,8 @@ static struct ast_frame *ast_rtp_read(struct ast_rtp_instance *instance, int rtc
 		rtp->lastividtimestamp = timestamp;
 		rtp->f.delivery.tv_sec = 0;
 		rtp->f.delivery.tv_usec = 0;
-		/* Pass the RTP marker bit as bit 0 in the subclass field.
-		 * This is ok because subclass is actually a bitmask, and
-		 * the low bits represent audio formats, that are not
-		 * involved here since we deal with video.
-		 */
-		if (mark)
-			rtp->f.subclass.codec |= 0x1;
+		/* Pass the RTP marker bit as bit */
+		ast_format_set_video_mark(&rtp->f.subclass.format);
 	} else {
 		/* TEXT -- samples is # of samples vs. 1000 */
 		if (!rtp->lastitexttimestamp)
@@ -2440,7 +2436,7 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
 	}
 
 	rtp->red->t140.frametype = AST_FRAME_TEXT;
-	rtp->red->t140.subclass.codec = AST_FORMAT_T140RED;
+	ast_format_set(&rtp->red->t140.subclass.format, AST_FORMAT_T140RED, 0);
 	rtp->red->t140.data.ptr = &rtp->red->buf_data;
 
 	rtp->red->t140.ts = 0;
diff --git a/res/res_rtp_multicast.c b/res/res_rtp_multicast.c
index 4ec71f26e4e4c56661716e9cd96fa10caa15d6ff..0e930d61f3504ec15efec649c52b262290eaf150 100644
--- a/res/res_rtp_multicast.c
+++ b/res/res_rtp_multicast.c
@@ -213,7 +213,7 @@ static int multicast_rtp_write(struct ast_rtp_instance *instance, struct ast_fra
 	}
 
 	/* Grab the actual payload number for when we create the RTP packet */
-	if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, frame->subclass.codec)) < 0) {
+	if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, &frame->subclass.format, 0)) < 0) {
 		return -1;
 	}
 
diff --git a/res/res_speech.c b/res/res_speech.c
index 46a846f0399c2edf2b22d7a1458fbf19ca93c60b..7a8d17e5aa8bdd370b32d6f7d4bf643d84239db8 100644
--- a/res/res_speech.c
+++ b/res/res_speech.c
@@ -169,23 +169,26 @@ int ast_speech_change(struct ast_speech *speech, const char *name, const char *v
 }
 
 /*! \brief Create a new speech structure using the engine specified */
-struct ast_speech *ast_speech_new(const char *engine_name, int formats)
+struct ast_speech *ast_speech_new(const char *engine_name, const struct ast_format_cap *cap)
 {
 	struct ast_speech_engine *engine = NULL;
 	struct ast_speech *new_speech = NULL;
-	int format = AST_FORMAT_SLINEAR;
+	struct ast_format_cap *joint = NULL;
+	struct ast_format best;
+
+	ast_format_set(&best, AST_FORMAT_SLINEAR, 0);
 
 	/* Try to find the speech recognition engine that was requested */
 	if (!(engine = find_engine(engine_name)))
 		return NULL;
 
 	/* Before even allocating the memory below do some codec negotiation, we choose the best codec possible and fall back to signed linear if possible */
-	if ((format = (engine->formats & formats)))
-		format = ast_best_codec(format);
-	else if ((engine->formats & AST_FORMAT_SLINEAR))
-		format = AST_FORMAT_SLINEAR;
-	else
+	if ((joint = ast_format_cap_joint(engine->formats, cap))) {
+		ast_best_codec(joint, &best);
+		joint = ast_format_cap_destroy(joint);
+	} else if (!ast_format_cap_iscompatible(engine->formats, &best)) {
 		return NULL;
+	}
 
 	/* Allocate our own speech structure, and try to allocate a structure from the engine too */
 	if (!(new_speech = ast_calloc(1, sizeof(*new_speech))))
@@ -201,13 +204,13 @@ struct ast_speech *ast_speech_new(const char *engine_name, int formats)
 	new_speech->engine = engine;
 
 	/* Can't forget the format audio is going to be in */
-	new_speech->format = format;
+	ast_format_copy(&new_speech->format, &best);
 
 	/* We are not ready to accept audio yet */
 	ast_speech_change_state(new_speech, AST_SPEECH_STATE_NOT_READY);
 
 	/* Pass ourselves to the engine so they can set us up some more and if they error out then do not create a structure */
-	if (engine->create(new_speech, format)) {
+	if (engine->create(new_speech, &best)) {
 		ast_mutex_destroy(&new_speech->lock);
 		ast_free(new_speech);
 		new_speech = NULL;
diff --git a/tests/test_format_api.c b/tests/test_format_api.c
new file mode 100644
index 0000000000000000000000000000000000000000..dc27725a55f7d2f33f441f6a505b752091735a8c
--- /dev/null
+++ b/tests/test_format_api.c
@@ -0,0 +1,859 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2010, Digium, Inc.
+ *
+ * David Vossel <dvossel@digium.com>
+ *
+ * See http://www.asterisk.org for more information about
+ * the Asterisk project. Please do not directly contact
+ * any of the maintainers of this project for assistance;
+ * the project provides a web site, mailing lists and IRC
+ * channels for your use.
+ *
+ * This program is free software, distributed under the terms of
+ * the GNU General Public License Version 2. See the LICENSE file
+ * at the top of the source tree.
+ */
+
+/*!
+ * \file
+ * \brief Tests for the ast_event API
+ *
+ * \author David Vossel <dvossel@digium.com>
+ *
+ * \ingroup tests
+ *
+ */
+
+/*** MODULEINFO
+	<depend>TEST_FRAMEWORK</depend>
+ ***/
+
+#include "asterisk.h"
+
+ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
+
+#include "asterisk/module.h"
+#include "asterisk/test.h"
+#include "asterisk/format.h"
+#include "asterisk/format_cap.h"
+#include "asterisk/strings.h"
+
+/*! These are the keys for accessing attributes */
+enum test_attr_keys {
+	TEST_ATTR_KEY_SAMP_RATE,
+	TEST_ATTR_KEY_STRING,
+};
+
+/*! These are the values for the TEST_ATTR_KEY_SAMP_RATE key */
+enum test_attr_vals_samp {
+	TEST_ATTR_VAL_SAMP_8KHZ  = (1 << 0),
+	TEST_ATTR_VAL_SAMP_12KHZ = (1 << 1),
+	TEST_ATTR_VAL_SAMP_16KHZ = (1 << 2),
+	TEST_ATTR_VAL_SAMP_32KHZ = (1 << 3),
+	TEST_ATTR_VAL_SAMP_48KHZ = (1 << 4),
+};
+
+/*! This is the attribute structure used for our test interface. */
+struct test_attr {
+	enum test_attr_vals_samp samp_flags;
+	char string[32];
+};
+
+static enum ast_format_cmp_res test_cmp(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2)
+{
+	struct test_attr *attr1 = (struct test_attr *) fattr1;
+	struct test_attr *attr2 = (struct test_attr *) fattr2;
+
+	if ((attr1->samp_flags == attr2->samp_flags) &&
+		!(strcmp(attr1->string, attr2->string))) {
+		return AST_FORMAT_CMP_EQUAL;
+	}
+	if ((attr1->samp_flags != (attr1->samp_flags & attr2->samp_flags)) ||
+		(!ast_strlen_zero(attr1->string) && strcmp(attr1->string, attr2->string))) {
+		return AST_FORMAT_CMP_NOT_EQUAL;
+	}
+	return AST_FORMAT_CMP_SUBSET;
+}
+
+static int test_getjoint(const struct ast_format_attr *fattr1, const struct ast_format_attr *fattr2, struct ast_format_attr *result)
+{
+	struct test_attr *attr1 = (struct test_attr *) fattr1;
+	struct test_attr *attr2 = (struct test_attr *) fattr2;
+	struct test_attr *attr_res = (struct test_attr *) result;
+	int joint = -1;
+
+	attr_res->samp_flags = (attr1->samp_flags & attr2->samp_flags);
+
+	if (attr_res->samp_flags) {
+		joint = 0;
+	}
+
+	if (!strcmp(attr1->string, attr2->string)) {
+		ast_copy_string(attr_res->string, attr1->string, sizeof(attr_res->string));
+		joint = 0;
+	}
+
+	return joint;
+}
+
+static void test_set(struct ast_format_attr *fattr, va_list ap)
+{
+	enum test_attr_keys key;
+	struct test_attr *attr = (struct test_attr *) fattr;
+	char *string;
+
+	for (key = va_arg(ap, int);
+		key != AST_FORMAT_ATTR_END;
+		key = va_arg(ap, int))
+	{
+		switch (key) {
+		case TEST_ATTR_KEY_SAMP_RATE:
+			attr->samp_flags = (va_arg(ap, int) | attr->samp_flags);
+			break;
+		case TEST_ATTR_KEY_STRING:
+			string = va_arg(ap, char *);
+			if (!ast_strlen_zero(string)) {
+				ast_copy_string(attr->string, string, sizeof(attr->string));
+			}
+			break;
+		default:
+			ast_log(LOG_WARNING, "unknown attribute type %d\n", key);
+		}
+	}
+}
+
+/*! uLaw does not actually have any attributes associated with it.
+ * This is just for the purpose of testing. We are guaranteed there
+ * will never exist a interface for uLaw already. */
+static struct ast_format_attr_interface test_interface = {
+	.id = AST_FORMAT_TESTLAW,
+	.format_attr_cmp = test_cmp,
+	.format_attr_get_joint = test_getjoint,
+	.format_attr_set = test_set
+};
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(format_test1)
+{
+	struct ast_format format1 = { 0, };
+	struct ast_format format2 = { 0, };
+	struct ast_format joint = { 0, };
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "ast_format_test1";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format with attributes.";
+		info->description =
+			"This test exercises the Ast Format API by creating and registering "
+			"a custom ast_format_attr_interface and performing various function "
+			"calls on ast_formats using the interface. ";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	if (ast_format_attr_reg_interface(&test_interface)) {
+		ast_test_status_update(test, "test_interface failed to register.\n");
+		return AST_TEST_FAIL;
+	}
+
+	/* set a format with a single attribute. */
+	ast_format_set(&format1, AST_FORMAT_TESTLAW, 1,
+		TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+		AST_FORMAT_ATTR_END);
+	if (ast_format_isset(&format1, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END)) {
+		ast_test_status_update(test, "format1 did not set number attribute correctly.\n");
+		return AST_TEST_FAIL;
+	}
+	if (!ast_format_isset(&format1, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_12KHZ, AST_FORMAT_ATTR_END)) {
+		ast_test_status_update(test, "format1 did not determine isset on number correctly. \n");
+		return AST_TEST_FAIL;
+	}
+
+	/* append the string attribute to a format with previous attributes already set */
+	ast_format_append(&format1,
+		TEST_ATTR_KEY_STRING,"String",
+		AST_FORMAT_ATTR_END);
+	if (ast_format_isset(&format1, TEST_ATTR_KEY_STRING, "String", AST_FORMAT_ATTR_END)) {
+		ast_test_status_update(test, "format1 did not set string attribute correctly.\n");
+		return AST_TEST_FAIL;
+	}
+	if (!ast_format_isset(&format1, TEST_ATTR_KEY_STRING, "Not a string", AST_FORMAT_ATTR_END)) {
+		ast_test_status_update(test, "format1 did not determine isset on string correctly. \n");
+		return AST_TEST_FAIL;
+	}
+
+	/* set format2 with both STRING and NUMBER at the same time */
+	ast_format_set(&format2, AST_FORMAT_TESTLAW, 1,
+		TEST_ATTR_KEY_STRING, "MOOOoo",
+		TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+		TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+		AST_FORMAT_ATTR_END);
+	/* perform isset with multiple key value pairs. */
+
+	if (ast_format_isset(&format2,
+			TEST_ATTR_KEY_STRING, "MOOOoo",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			AST_FORMAT_ATTR_END)) {
+
+		ast_test_status_update(test, "format2 did not set attributes correctly.\n");
+		return AST_TEST_FAIL;
+	}
+	if (!ast_format_isset(&format2,
+			TEST_ATTR_KEY_STRING, "WRONG",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			AST_FORMAT_ATTR_END)) {
+
+		ast_test_status_update(test, "format2 did not deterine isset correctly.\n");
+		return AST_TEST_FAIL;
+	}
+
+	/* get joint attributes between format1 and format2. */
+	if (ast_format_joint(&format1, &format2, &joint)) {
+		ast_test_status_update(test, "failed to get joint attributes.\n");
+		return AST_TEST_FAIL;
+	}
+	if (ast_format_isset(&joint, TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ, AST_FORMAT_ATTR_END)) {
+		ast_test_status_update(test, "joint attribute was not what we expected.\n");
+		return AST_TEST_FAIL;
+	}
+
+	/* exercise compare functions */
+	if (ast_format_cmp(&format1, &format2) != AST_FORMAT_CMP_NOT_EQUAL) {
+		ast_test_status_update(test, "cmp 1 failed.\n");
+		return AST_TEST_FAIL;
+	}
+	if (ast_format_cmp(&format1, &format1) != AST_FORMAT_CMP_EQUAL) {
+		ast_test_status_update(test, "cmp 2 failed.\n");
+		return AST_TEST_FAIL;
+	}
+	if (ast_format_cmp(&joint, &format1) != AST_FORMAT_CMP_SUBSET) {
+		ast_test_status_update(test, "cmp 3 failed.\n");
+		return AST_TEST_FAIL;
+	}
+
+	/* unregister interface */
+	if (ast_format_attr_unreg_interface(&test_interface)) {
+		ast_test_status_update(test, "test_interface failed to unregister.\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(format_test2)
+{
+	struct ast_format format = { 0, };
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "ast_format_test2";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format unique id and category system";
+		info->description =
+			"This test exercises the Ast Format unique id and category "
+			"system by creating formats of various types and verifying "
+			"their category matches what we expect.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	ast_format_set(&format, AST_FORMAT_ULAW, 0);
+	if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_AUDIO) {
+		ast_test_status_update(test, "audio type failed\n");
+		return AST_TEST_FAIL;
+	}
+
+	ast_format_set(&format, AST_FORMAT_H264, 0);
+	if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_VIDEO) {
+		ast_test_status_update(test, "video type failed\n");
+		return AST_TEST_FAIL;
+	}
+
+	ast_format_set(&format, AST_FORMAT_JPEG, 0);
+	if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_IMAGE) {
+		ast_test_status_update(test, "image type failed\n");
+		return AST_TEST_FAIL;
+	}
+
+	ast_format_set(&format, AST_FORMAT_T140, 0);
+	if (AST_FORMAT_GET_TYPE(format.id) != AST_FORMAT_TYPE_TEXT) {
+		ast_test_status_update(test, "text type failed\n");
+		return AST_TEST_FAIL;
+	}
+
+	return AST_TEST_PASS;
+}
+
+static int container_test1_helper(struct ast_format_cap *cap1, struct ast_format_cap *cap2, struct ast_test *test)
+{
+
+	int res = AST_TEST_PASS;
+	struct ast_format_cap *cap_joint;
+	struct ast_format tmpformat;
+
+	if (ast_format_attr_reg_interface(&test_interface)) {
+		ast_test_status_update(test, "test_interface failed to register.\n");
+		ast_format_cap_destroy(cap1);
+		ast_format_cap_destroy(cap2);
+		return AST_TEST_FAIL;
+	}
+
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_G722, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_H264, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_H263, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_T140, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0));
+	ast_format_cap_add(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_STRING, "testing caps hooray",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_32KHZ,
+			AST_FORMAT_ATTR_END));
+
+	/* Test is compatible */
+	if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0)) ||
+		!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
+		!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
+		!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_H264, 0)) ||
+		!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0)) ||
+		!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
+		ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 1.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* Test things that are not compatible */
+	if (ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_SPEEX, 0)) ||
+		ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_SPEEX16, 0)) ||
+		ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_H261, 0))) {
+		ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 2.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* Test compatiblity with format with attributes. */
+	if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_STRING, "testing caps hooray",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			AST_FORMAT_ATTR_END))) {
+
+		ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 3.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	if (!ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			AST_FORMAT_ATTR_END))) {
+
+		ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 4.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	if (ast_format_cap_iscompatible(cap1, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ, /* 48khz was not compatible, so this should fail iscompatible check */
+			AST_FORMAT_ATTR_END))) {
+
+		ast_test_status_update(test, "ast cap1 failed to properly detect compatibility test 5.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* Lets start testing the functions that compare ast_format_cap objects.
+	 * Genreate the cap2 object to contain some similar formats as cap1
+	 * and some different formats as well. */
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_SIREN7, 0));
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_H261, 0));
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_T140, 0));
+	ast_format_cap_add(cap2, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_STRING, "testing caps hooray",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_12KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_32KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ,
+			AST_FORMAT_ATTR_END));
+
+
+	/* find joint formats between cap1 and cap2 */
+	cap_joint = ast_format_cap_joint(cap1, cap2);
+
+	if (!cap_joint) {
+		ast_test_status_update(test, "failed to create joint capabilities correctly.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* determine if cap_joint is what we think it should be */
+	if (!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
+		!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
+		!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0)) ||
+		!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_STRING, "testing caps hooray",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			AST_FORMAT_ATTR_END))) {
+
+		ast_test_status_update(test, "ast cap_joint failed to properly detect compatibility test 1.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* make sure joint cap does not have formats that should not be there */
+	if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_SIREN7, 0)) ||
+		ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_TESTLAW, 1,
+			TEST_ATTR_KEY_STRING, "testing caps hooray",
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_8KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_16KHZ,
+			TEST_ATTR_KEY_SAMP_RATE, TEST_ATTR_VAL_SAMP_48KHZ,
+			AST_FORMAT_ATTR_END))) {
+
+		ast_test_status_update(test, "ast cap_joint failed to properly detect compatibility test 1.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* Lets test removing a capability */
+	if (ast_format_cap_remove(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
+		ast_test_status_update(test, "ast_format_cap_remove failed. \n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* Lets make sure what we just removed does not still exist */
+	if (ast_format_cap_iscompatible(cap_joint, &tmpformat)) {
+		ast_test_status_update(test, "ast_format_cap_remove failed 2. \n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* Lets test removing a capability by id.*/
+	if (ast_format_cap_remove_byid(cap_joint, AST_FORMAT_GSM)) {
+		ast_test_status_update(test, "ast_format_cap_remove failed 3. \n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* Lets make sure what we just removed does not still exist */
+	if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0))) {
+		ast_test_status_update(test, "ast_format_cap_remove failed 4. \n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* lets test getting joint formats by type */
+	ast_format_cap_destroy(cap_joint);
+	if (!(cap_joint = ast_format_cap_get_type(cap1, AST_FORMAT_TYPE_VIDEO))) {
+		ast_test_status_update(test, "ast_format_cap_get_type failed.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* lets make sure our joint capability structure has what we expect */
+	if (!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_H264, 0)) ||
+		!ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_H263, 0))) {
+		ast_test_status_update(test, "get_type failed 2.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	/* now make sure joint does not have anything but video */
+	if (ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ALAW, 0)) ||
+		ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0)) ||
+		ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0)) ||
+		ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_JPEG, 0)) ||
+		ast_format_cap_iscompatible(cap_joint, ast_format_set(&tmpformat, AST_FORMAT_T140, 0))) {
+		ast_test_status_update(test, "get_type failed 3.\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* now lets remove everythign from cap_joint */
+	ast_format_cap_remove_all(cap_joint);
+	if (!ast_format_cap_is_empty(cap_joint)) {
+		ast_test_status_update(test, "failed to remove all\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+	/* now lets add all by type */
+	ast_format_cap_add_all_by_type(cap_joint, AST_FORMAT_TYPE_AUDIO);
+	if (ast_format_cap_is_empty(cap_joint)) {
+			ast_test_status_update(test, "failed to add all by type AUDIO\n");
+			res = AST_TEST_FAIL;
+	}
+	ast_format_cap_iter_start(cap_joint);
+	while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
+		if (AST_FORMAT_GET_TYPE(tmpformat.id) != AST_FORMAT_TYPE_AUDIO) {
+			ast_test_status_update(test, "failed to add all by type AUDIO\n");
+			res = AST_TEST_FAIL;
+			ast_format_cap_iter_end(cap_joint);
+			goto test3_cleanup;
+		}
+	}
+	ast_format_cap_iter_end(cap_joint);
+
+	/* test append */
+	ast_format_cap_append(cap_joint, cap1);
+	ast_format_cap_iter_start(cap1);
+	while (!(ast_format_cap_iter_next(cap1, &tmpformat))) {
+		if (!ast_format_cap_iscompatible(cap_joint, &tmpformat)) {
+			ast_test_status_update(test, "failed to append format capabilities.\n");
+			res = AST_TEST_FAIL;
+			ast_format_cap_iter_end(cap1);
+			goto test3_cleanup;
+		}
+	}
+	ast_format_cap_iter_end(cap1);
+
+	/* test copy */
+	cap1 = ast_format_cap_destroy(cap1);
+	cap1 = ast_format_cap_dup(cap_joint);
+	if (!ast_format_cap_identical(cap_joint, cap1)) {
+			ast_test_status_update(test, "failed to copy capabilities\n");
+			res = AST_TEST_FAIL;
+			goto test3_cleanup;
+	}
+
+	/* test remove by type */
+	ast_format_cap_remove_bytype(cap_joint, AST_FORMAT_TYPE_AUDIO);
+	if (ast_format_cap_has_type(cap_joint, AST_FORMAT_TYPE_AUDIO)) {
+		ast_test_status_update(test, "failed to remove all by type audio\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	if (!ast_format_cap_has_type(cap_joint, AST_FORMAT_TYPE_TEXT)) { /* it should still have text */
+		ast_test_status_update(test, "failed to remove all by type audio\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+	ast_format_cap_iter_start(cap_joint);
+	while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
+		if (AST_FORMAT_GET_TYPE(tmpformat.id) == AST_FORMAT_TYPE_AUDIO) {
+			ast_test_status_update(test, "failed to remove all by type audio\n");
+			res = AST_TEST_FAIL;
+			ast_format_cap_iter_end(cap_joint);
+			goto test3_cleanup;
+		}
+	}
+	ast_format_cap_iter_end(cap_joint);
+
+	/* test add all */
+	ast_format_cap_remove_all(cap_joint);
+	ast_format_cap_add_all(cap_joint);
+	{
+		int video = 0, audio = 0, text = 0, image = 0;
+		ast_format_cap_iter_start(cap_joint);
+		while (!(ast_format_cap_iter_next(cap_joint, &tmpformat))) {
+			switch (AST_FORMAT_GET_TYPE(tmpformat.id)) {
+			case AST_FORMAT_TYPE_AUDIO:
+				audio++;
+				break;
+			case AST_FORMAT_TYPE_VIDEO:
+				video++;
+				break;
+			case AST_FORMAT_TYPE_TEXT:
+				text++;
+				break;
+			case AST_FORMAT_TYPE_IMAGE:
+				image++;
+				break;
+			}
+		}
+		ast_format_cap_iter_end(cap_joint);
+		if (!video || !audio || !text || !image) {
+			ast_test_status_update(test, "failed to add all\n");
+			res = AST_TEST_FAIL;
+			ast_format_cap_iter_end(cap_joint);
+			goto test3_cleanup;
+		}
+	}
+
+	/* test copy2 */
+	ast_format_cap_copy(cap2, cap_joint);
+	if (!ast_format_cap_identical(cap2, cap_joint)) {
+		ast_test_status_update(test, "ast_format_cap_copy failed\n");
+		res = AST_TEST_FAIL;
+		goto test3_cleanup;
+	}
+
+test3_cleanup:
+	ast_format_cap_destroy(cap1);
+	ast_format_cap_destroy(cap2);
+	ast_format_cap_destroy(cap_joint);
+
+	/* unregister interface */
+	if (ast_format_attr_unreg_interface(&test_interface)) {
+		ast_test_status_update(test, "test_interface failed to unregister.\n");
+		res = AST_TEST_FAIL;
+	}
+
+	return res;
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test1_nolock)
+{
+	struct ast_format_cap *cap1;
+	struct ast_format_cap *cap2;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test_1_no_locking";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format and ast_format_cap structures, no locking";
+		info->description =
+			"This test exercises the Ast Format Capability API by creating "
+			"capability structures and performing various API calls on them.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	cap1 = ast_format_cap_alloc_nolock();
+	cap2 = ast_format_cap_alloc_nolock();
+
+	if (!cap1 || !cap2) {
+		ast_test_status_update(test, "cap alloc failed.\n");
+		return AST_TEST_FAIL;
+	}
+	return container_test1_helper(cap1, cap2, test);
+}
+
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test1_withlock)
+{
+	struct ast_format_cap *cap1;
+	struct ast_format_cap *cap2;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test1_with_locking";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format and ast_format_cap structures, with locking";
+		info->description =
+			"This test exercises the Ast Format Capability API by creating "
+			"capability structures and performing various API calls on them.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	cap1 = ast_format_cap_alloc();
+	cap2 = ast_format_cap_alloc();
+
+	if (!cap1 || !cap2) {
+		ast_test_status_update(test, "cap alloc failed.\n");
+		return AST_TEST_FAIL;
+	}
+	return container_test1_helper(cap1, cap2, test);
+}
+
+static int container_test2_no_locking_helper(struct ast_format_cap *cap, struct ast_test *test)
+{
+	int num = 0;
+	struct ast_format tmpformat = { 0, };
+
+	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_GSM, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_ULAW, 0));
+	ast_format_cap_add(cap, ast_format_set(&tmpformat, AST_FORMAT_G722, 0));
+
+	ast_format_cap_iter_start(cap);
+	while (!ast_format_cap_iter_next(cap, &tmpformat)) {
+		num++;
+	}
+	ast_format_cap_iter_end(cap);
+
+	ast_format_cap_iter_start(cap);
+	while (!ast_format_cap_iter_next(cap, &tmpformat)) {
+		num++;
+	}
+	ast_format_cap_iter_end(cap);
+
+	ast_format_cap_destroy(cap);
+	ast_test_status_update(test, "%d items iterated over\n", num);
+	return (num == 6) ? AST_TEST_PASS : AST_TEST_FAIL;
+
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test2_no_locking)
+{
+	struct ast_format_cap *cap;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test2_no_locking";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format_cap iterator, no locking";
+		info->description =
+			"This test exercises the Ast Capability API iterators.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	cap = ast_format_cap_alloc_nolock();
+	if (!cap) {
+		ast_test_status_update(test, "alloc failed\n");
+		return AST_TEST_FAIL;
+	}
+	return container_test2_no_locking_helper(cap, test);
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test2_with_locking)
+{
+	struct ast_format_cap *cap;
+
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test2_with_locking";
+		info->category = "/main/format/";
+		info->summary = "Test ast_format_cap iterator, with locking";
+		info->description =
+			"This test exercises the Ast Capability API iterators.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	cap = ast_format_cap_alloc();
+	if (!cap) {
+		ast_test_status_update(test, "alloc failed\n");
+		return AST_TEST_FAIL;
+	}
+	return container_test2_no_locking_helper(cap, test);
+}
+
+
+static int container_test3_helper(int nolocking, struct ast_test *test)
+{
+	int x;
+	int res = AST_TEST_PASS;
+	struct ast_format_cap *cap1;
+	struct ast_format_cap *cap2;
+	struct ast_format_cap *joint;
+
+	for (x = 0; x < 2000; x++) {
+		if (nolocking) {
+			cap1 = ast_format_cap_alloc_nolock();
+			cap2 = ast_format_cap_alloc_nolock();
+			joint = ast_format_cap_alloc_nolock();
+		} else {
+			cap1 = ast_format_cap_alloc();
+			cap2 = ast_format_cap_alloc();
+			joint = ast_format_cap_alloc();
+		}
+		if (!cap1 || !cap2 || !joint) {
+			ast_test_status_update(test, "cap alloc fail\n");
+			return AST_TEST_FAIL;
+		}
+		ast_format_cap_add_all(cap1);
+		ast_format_cap_add_all_by_type(cap2, AST_FORMAT_TYPE_AUDIO);
+		ast_format_cap_joint_copy(cap1, cap2, joint);
+		if (!(ast_format_cap_identical(cap2, joint))) {
+			ast_test_status_update(test, "failed identical test\n");
+			res = AST_TEST_FAIL;
+			cap1 = ast_format_cap_destroy(cap1);
+			cap2 = ast_format_cap_destroy(cap2);
+			joint = ast_format_cap_destroy(joint);
+			break;
+		}
+		cap1 = ast_format_cap_destroy(cap1);
+		cap2 = ast_format_cap_destroy(cap2);
+		joint = ast_format_cap_destroy(joint);
+	}
+	return res;
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test3_nolock)
+{
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test3_no_locking";
+		info->category = "/main/format/";
+		info->summary = "Load Test ast_format_cap no locking.";
+		info->description =
+			"This test exercises the Ast Capability API and its iterators for the purpose "
+			"of measuring performance.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	return container_test3_helper(1, test);
+}
+
+/*!
+ * \internal
+ */
+AST_TEST_DEFINE(container_test3_withlock)
+{
+	switch (cmd) {
+	case TEST_INIT:
+		info->name = "container_test3_with_locking";
+		info->category = "/main/format/";
+		info->summary = "Load Test ast_format_cap with locking.";
+		info->description =
+			"This test exercises the Ast Capability API and its iterators for the purpose "
+			"of measuring performance.";
+		return AST_TEST_NOT_RUN;
+	case TEST_EXECUTE:
+		break;
+	}
+
+	return container_test3_helper(0, test);
+}
+
+static int unload_module(void)
+{
+	AST_TEST_UNREGISTER(format_test1);
+	AST_TEST_UNREGISTER(format_test2);
+	AST_TEST_UNREGISTER(container_test1_nolock);
+	AST_TEST_UNREGISTER(container_test1_withlock);
+	AST_TEST_UNREGISTER(container_test2_no_locking);
+	AST_TEST_UNREGISTER(container_test2_with_locking);
+	AST_TEST_UNREGISTER(container_test3_nolock);
+	AST_TEST_UNREGISTER(container_test3_withlock);
+
+	return 0;
+}
+
+static int load_module(void)
+{
+	AST_TEST_REGISTER(format_test1);
+	AST_TEST_REGISTER(format_test2);
+	AST_TEST_REGISTER(container_test1_nolock);
+	AST_TEST_REGISTER(container_test1_withlock);
+	AST_TEST_REGISTER(container_test2_no_locking);
+	AST_TEST_REGISTER(container_test2_with_locking);
+	AST_TEST_REGISTER(container_test3_nolock);
+	AST_TEST_REGISTER(container_test3_withlock);
+
+	return AST_MODULE_LOAD_SUCCESS;
+}
+
+AST_MODULE_INFO_STANDARD(ASTERISK_GPL_KEY, "ast_format API Tests");