diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index ed0f790..72200a3 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3973,6 +3973,8 @@ static struct ast_channel *sip_new(struct sip_pvt *i, int state, const char *tit
 	else
 		tmp->tech = &sip_tech;
 
+	i->prefcodec = 0;
+
 	/* 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 */
@@ -6413,7 +6415,7 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p)
 		dest.sin_port = sin.sin_port;
 	}
 
-	capability = p->jointcapability;
+	capability = p->jointcapability? p->jointcapability : p->capability;
 
 
 	if (option_debug > 1) {
diff --git a/include/asterisk/sip_def.h b/include/asterisk/sip_def.h
new file mode 100644
index 0000000..ef8c501
--- /dev/null
+++ b/include/asterisk/sip_def.h
@@ -0,0 +1,355 @@
+#include "asterisk/astobj.h"
+
+/* chan_sip types */
+
+/*! \brief States for the INVITE transaction, not the dialog
+        \note this is for the INVITE that sets up the dialog
+*/
+#define SIP_MAX_HEADERS              64               /*!< Max amount of SIP headers to read */
+#define SIP_MAX_LINES                64               /*!< Max amount of lines in SIP attachment (like SDP) */
+#define SIP_MAX_PACKET               4096             /*!< Also from RFC 3261 (2543), should sub headers tho */
+#define RTP     1
+#define NO_RTP  0
+
+/*! \brief Authorization scheme for call transfers
+\note Not a bitfield flag, since there are plans for other modes,
+        like "only allow transfers for authenticated devices" */
+enum transfermodes {
+        TRANSFER_OPENFORALL,            /*!< Allow all SIP transfers */
+        TRANSFER_CLOSED,                /*!< Allow no SIP transfers */
+};
+
+/*! \brief Authentication types - proxy or www authentication
+        \note Endpoints, like Asterisk, should always use WWW authentication to
+        allow multiple authentications in the same call - to the proxy and
+        to the end point.
+*/
+enum sip_auth_type {
+        PROXY_AUTH,
+        WWW_AUTH,
+};
+
+enum sip_result {
+        AST_SUCCESS = 0,
+        AST_FAILURE = -1,
+};
+enum subscriptiontype {
+        NONE = 0,
+        XPIDF_XML,
+        DIALOG_INFO_XML,
+        CPIM_PIDF_XML,
+        PIDF_XML,
+        MWI_NOTIFICATION
+};
+
+enum invitestates {
+        INV_NONE = 0,           /*!< No state at all, maybe not an INVITE dialog */
+        INV_CALLING = 1,        /*!< Invite sent, no answer */
+        INV_PROCEEDING = 2,     /*!< We got/sent 1xx message */
+        INV_EARLY_MEDIA = 3,    /*!< We got 18x message with to-tag back */
+        INV_COMPLETED = 4,      /*!< Got final response with error. Wait for ACK, then CONFIRMED */
+        INV_CONFIRMED = 5,      /*!< Confirmed response - we've got an ack (Incoming calls only) */
+        INV_TERMINATED = 6,     /*!< Transaction done - either successful (AST_STATE_UP) or failed, but done
+                                     The only way out of this is a BYE from one side */
+        INV_CANCELLED = 7,      /*!< Transaction cancelled by client or server in non-terminated state */
+};
+/*! \brief T38 States for a call */
+enum t38state {
+        T38_DISABLED = 0,                /*!< Not enabled */
+        T38_LOCAL_DIRECT,                /*!< Offered from local */
+        T38_LOCAL_REINVITE,              /*!< Offered from local - REINVITE */
+        T38_PEER_DIRECT,                 /*!< Offered from peer */
+        T38_PEER_REINVITE,               /*!< Offered from peer - REINVITE */
+        T38_ENABLED                      /*!< Negotiated (enabled) */
+};
+
+/*! \brief T.38 channel settings (at some point we need to make this alloc'ed */
+struct t38properties {
+        struct ast_flags t38support;    /*!< Flag for udptl, rtp or tcp support for this session */
+        int capability;                 /*!< Our T38 capability */
+        int peercapability;             /*!< Peers T38 capability */
+        int jointcapability;            /*!< Supported T38 capability at both ends */
+        enum t38state state;            /*!< T.38 state */
+};
+/*! \brief sip_request: The data grabbed from the UDP socket */
+struct sip_request {
+        char *rlPart1;          /*!< SIP Method Name or "SIP/2.0" protocol version */
+        char *rlPart2;          /*!< The Request URI or Response Status */
+        int len;                /*!< Length */
+        int headers;            /*!< # of SIP Headers */
+        int method;             /*!< Method of this request */
+        int lines;              /*!< Body Content */
+        unsigned int flags;     /*!< SIP_PKT Flags for this packet */
+        char *header[SIP_MAX_HEADERS];
+        char *line[SIP_MAX_LINES];
+        char data[SIP_MAX_PACKET];
+        unsigned int sdp_start; /*!< the line number where the SDP begins */
+        unsigned int sdp_end;   /*!< the line number where the SDP ends */
+};
+
+struct sip_pvt {
+        ast_mutex_t lock;                       /*!< Dialog private lock */
+        int method;                             /*!< SIP method that opened this dialog */
+        enum invitestates invitestate;          /*!< The state of the INVITE transaction only */
+        AST_DECLARE_STRING_FIELDS(
+                AST_STRING_FIELD(callid);       /*!< Global CallID */
+                AST_STRING_FIELD(randdata);     /*!< Random data */
+                AST_STRING_FIELD(accountcode);  /*!< Account code */
+                AST_STRING_FIELD(realm);        /*!< Authorization realm */
+                AST_STRING_FIELD(nonce);        /*!< Authorization nonce */
+                AST_STRING_FIELD(opaque);       /*!< Opaque nonsense */
+                AST_STRING_FIELD(qop);          /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
+                AST_STRING_FIELD(domain);       /*!< Authorization domain */
+                AST_STRING_FIELD(from);         /*!< The From: header */
+                AST_STRING_FIELD(useragent);    /*!< User agent in SIP request */
+                AST_STRING_FIELD(exten);        /*!< Extension where to start */
+                AST_STRING_FIELD(context);      /*!< Context for this call */
+                AST_STRING_FIELD(subscribecontext); /*!< Subscribecontext */
+                AST_STRING_FIELD(subscribeuri); /*!< Subscribecontext */
+                AST_STRING_FIELD(fromdomain);   /*!< Domain to show in the from field */
+                AST_STRING_FIELD(fromuser);     /*!< User to show in the user field */
+                AST_STRING_FIELD(fromname);     /*!< Name to show in the user field */
+                AST_STRING_FIELD(tohost);       /*!< Host we should put in the "to" field */
+                AST_STRING_FIELD(language);     /*!< Default language for this call */
+                AST_STRING_FIELD(mohinterpret); /*!< MOH class to use when put on hold */
+                AST_STRING_FIELD(mohsuggest);   /*!< MOH class to suggest when putting a peer on hold */
+                AST_STRING_FIELD(rdnis);        /*!< Referring DNIS */
+                AST_STRING_FIELD(theirtag);     /*!< Their tag */
+                AST_STRING_FIELD(username);     /*!< [user] name */
+                AST_STRING_FIELD(peername);     /*!< [peer] name, not set if [user] */
+                AST_STRING_FIELD(authname);     /*!< Who we use for authentication */
+                AST_STRING_FIELD(uri);          /*!< Original requested URI */
+                AST_STRING_FIELD(okcontacturi); /*!< URI from the 200 OK on INVITE */
+                AST_STRING_FIELD(peersecret);   /*!< Password */
+                AST_STRING_FIELD(peermd5secret);
+                AST_STRING_FIELD(cid_num);      /*!< Caller*ID number */
+                AST_STRING_FIELD(cid_name);     /*!< Caller*ID name */
+                AST_STRING_FIELD(via);          /*!< Via: header */
+                AST_STRING_FIELD(fullcontact);  /*!< The Contact: that the UA registers with us */
+                AST_STRING_FIELD(our_contact);  /*!< Our contact header */
+                AST_STRING_FIELD(rpid);         /*!< Our RPID header */
+                AST_STRING_FIELD(rpid_from);    /*!< Our RPID From header */
+        );
+        unsigned int ocseq;                     /*!< Current outgoing seqno */
+        unsigned int icseq;                     /*!< Current incoming seqno */
+        ast_group_t callgroup;                  /*!< Call group */
+        ast_group_t pickupgroup;                /*!< Pickup group */
+        int lastinvite;                         /*!< Last Cseq of invite */
+        int lastnoninvite;                      /*!< Last Cseq of non-invite */
+        struct ast_flags flags[2];              /*!< SIP_ flags */
+        int timer_t1;                           /*!< SIP timer T1, ms rtt */
+        unsigned int sipoptions;                /*!< Supported SIP options on the other end */
+        struct ast_codec_pref prefs;            /*!< codec prefs */
+        int capability;                         /*!< Special capability (codec) */
+        int jointcapability;                    /*!< Supported capability at both ends (codecs) */
+        int peercapability;                     /*!< Supported peer capability */
+        int prefcodec;                          /*!< Preferred codec (outbound only) */
+        int noncodeccapability;                 /*!< DTMF RFC2833 telephony-event */
+        int jointnoncodeccapability;            /*!< Joint Non codec capability */
+        int redircodecs;                        /*!< Redirect codecs */
+        int maxcallbitrate;                     /*!< Maximum Call Bitrate for Video Calls */
+        struct t38properties t38;               /*!< T38 settings */
+        struct sockaddr_in udptlredirip;        /*!< Where our T.38 UDPTL should be going if not to us */
+        struct ast_udptl *udptl;                /*!< T.38 UDPTL session */
+        int callingpres;                        /*!< Calling presentation */
+        int authtries;                          /*!< Times we've tried to authenticate */
+        int expiry;                             /*!< How long we take to expire */
+        long branch;                            /*!< The branch identifier of this session */
+        char tag[11];                           /*!< Our tag for this session */
+        int sessionid;                          /*!< SDP Session ID */
+        int sessionversion;                     /*!< SDP Session Version */
+        struct sockaddr_in sa;                  /*!< Our peer */
+        struct sockaddr_in redirip;             /*!< Where our RTP should be going if not to us */
+        struct sockaddr_in vredirip;            /*!< Where our Video RTP should be going if not to us */
+        time_t lastrtprx;                       /*!< Last RTP received */
+        time_t lastrtptx;                       /*!< Last RTP sent */
+        int rtptimeout;                         /*!< RTP timeout time */
+        struct sockaddr_in recv;                /*!< Received as */
+        struct in_addr ourip;                   /*!< Our IP */
+        struct ast_channel *owner;              /*!< Who owns us (if we have an owner) */
+        struct sip_route *route;                /*!< Head of linked list of routing steps (fm Record-Route) */
+        int route_persistant;                   /*!< Is this the "real" route? */
+        struct sip_auth *peerauth;              /*!< Realm authentication */
+        int noncecount;                         /*!< Nonce-count */
+        char lastmsg[256];                      /*!< Last Message sent/received */
+        int amaflags;                           /*!< AMA Flags */
+        int pendinginvite;                      /*!< Any pending invite ? (seqno of this) */
+        struct sip_request initreq;             /*!< Request that opened the latest transaction
+                                                     within this SIP dialog */
+
+        int maxtime;                            /*!< Max time for first response */
+        int initid;                             /*!< Auto-congest ID if appropriate (scheduler) */
+        int autokillid;                         /*!< Auto-kill ID (scheduler) */
+        enum transfermodes allowtransfer;       /*!< REFER: restriction scheme */
+        struct sip_refer *refer;                /*!< REFER: SIP transfer data structure */
+        enum subscriptiontype subscribed;       /*!< SUBSCRIBE: Is this dialog a subscription?  */
+        int stateid;                            /*!< SUBSCRIBE: ID for devicestate subscriptions */
+        int laststate;                          /*!< SUBSCRIBE: Last known extension state */
+        int dialogver;                          /*!< SUBSCRIBE: Version for subscription dialog-info */
+
+        struct ast_dsp *vad;                    /*!< Voice Activation Detection dsp */
+
+        struct sip_peer *relatedpeer;           /*!< If this dialog is related to a peer, which one
+                                                        Used in peerpoke, mwi subscriptions */
+        struct sip_registry *registry;          /*!< If this is a REGISTER dialog, to which registry */
+        struct ast_rtp *rtp;                    /*!< RTP Session */
+        struct ast_rtp *vrtp;                   /*!< Video RTP session */
+        struct sip_pkt *packets;                /*!< Packets scheduled for re-transmission */
+        struct sip_history_head *history;       /*!< History of this SIP dialog */
+        size_t history_entries;                 /*!< Number of entires in the history */
+        struct ast_variable *chanvars;          /*!< Channel variables to set for inbound call */
+        struct sip_pvt *next;                   /*!< Next dialog in chain */
+        struct sip_invite_param *options;       /*!< Options for INVITE */
+        int autoframing;
+};
+
+/*! \brief sip packet - raw format for outbound packets that are sent or scheduled for transmission */
+struct sip_pkt {
+        struct sip_pkt *next;                   /*!< Next packet in linked list */
+        int retrans;                            /*!< Retransmission number */
+        int method;                             /*!< SIP method for this packet */
+        int seqno;                              /*!< Sequence number */
+        unsigned int flags;                     /*!< non-zero if this is a response packet (e.g. 200 OK) */
+        struct sip_pvt *owner;                  /*!< Owner AST call */
+        int retransid;                          /*!< Retransmission ID */
+        int timer_a;                            /*!< SIP timer A, retransmission timer */
+        int timer_t1;                           /*!< SIP Timer T1, estimated RTT or 500 ms */
+        int packetlen;                          /*!< Length of packet */
+        char data[0];
+};
+
+/*! \brief Parameters to the transmit_invite function */
+struct sip_invite_param {
+        const char *distinctive_ring;   /*!< Distinctive ring header */
+        int addsipheaders;              /*!< Add extra SIP headers */
+        const char *uri_options;        /*!< URI options to add to the URI */
+        const char *vxml_url;           /*!< VXML url for Cisco phones */
+        char *auth;                     /*!< Authentication */
+        char *authheader;               /*!< Auth header */
+        enum sip_auth_type auth_type;   /*!< Authentication type */
+        const char *replaces;           /*!< Replaces header for call transfers */
+        int transfer;                   /*!< Flag - is this Invite part of a SIP transfer? (invite/replaces) */
+};
+/*! \brief Structure to save routing information for a SIP session */
+struct sip_route {
+        struct sip_route *next;
+        char hop[0];
+};
+/*! \brief Structure for SIP peer data, we place calls to peers if registered  or fixed IP address (host) */
+/* XXX field 'name' must be first otherwise sip_addrcmp() will fail */
+struct sip_peer {
+        ASTOBJ_COMPONENTS(struct sip_peer);     /*!< name, refcount, objflags,  object pointers */
+                                        /*!< peer->name is the unique name of this object */
+        char secret[80];                /*!< Password */
+        char md5secret[80];             /*!< Password in MD5 */
+        struct sip_auth *auth;          /*!< Realm authentication list */
+        char context[AST_MAX_CONTEXT];  /*!< Default context for incoming calls */
+        char subscribecontext[AST_MAX_CONTEXT]; /*!< Default context for subscriptions */
+        char username[80];              /*!< Temporary username until registration */
+        char accountcode[AST_MAX_ACCOUNT_CODE]; /*!< Account code */
+        int amaflags;                   /*!< AMA Flags (for billing) */
+        char tohost[MAXHOSTNAMELEN];    /*!< If not dynamic, IP address */
+        char regexten[AST_MAX_EXTENSION]; /*!< Extension to register (if regcontext is used) */
+        char fromuser[80];              /*!< From: user when calling this peer */
+        char fromdomain[MAXHOSTNAMELEN];        /*!< From: domain when calling this peer */
+        char fullcontact[256];          /*!< Contact registered with us (not in sip.conf) */
+        char cid_num[80];               /*!< Caller ID num */
+        char cid_name[80];              /*!< Caller ID name */
+        int callingpres;                /*!< Calling id presentation */
+        int inUse;                      /*!< Number of calls in use */
+        int inRinging;                  /*!< Number of calls ringing */
+        int onHold;                     /*!< Peer has someone on hold */
+        int call_limit;                 /*!< Limit of concurrent calls */
+        enum transfermodes allowtransfer;       /*! SIP Refer restriction scheme */
+        char vmexten[AST_MAX_EXTENSION]; /*!< Dialplan extension for MWI notify message*/
+        char mailbox[AST_MAX_EXTENSION]; /*!< Mailbox setting for MWI checks */
+        char language[MAX_LANGUAGE];    /*!<  Default language for prompts */
+        char mohinterpret[MAX_MUSICCLASS];/*!<  Music on Hold class */
+        char mohsuggest[MAX_MUSICCLASS];/*!<  Music on Hold class */
+        char useragent[256];            /*!<  User agent in SIP request (saved from registration) */
+        struct ast_codec_pref prefs;    /*!<  codec prefs */
+        int lastmsgssent;
+        time_t  lastmsgcheck;           /*!<  Last time we checked for MWI */
+        unsigned int sipoptions;        /*!<  Supported SIP options */
+        struct ast_flags flags[2];      /*!<  SIP_ flags */
+        int expire;                     /*!<  When to expire this peer registration */
+        int capability;                 /*!<  Codec capability */
+        int rtptimeout;                 /*!<  RTP timeout */
+        int rtpholdtimeout;             /*!<  RTP Hold Timeout */
+        int rtpkeepalive;               /*!<  Send RTP packets for keepalive */
+        ast_group_t callgroup;          /*!<  Call group */
+        ast_group_t pickupgroup;        /*!<  Pickup group */
+        struct sockaddr_in addr;        /*!<  IP address of peer */
+        int maxcallbitrate;             /*!< Maximum Bitrate for a video call */
+
+        /* Qualification */
+        struct sip_pvt *call;           /*!<  Call pointer */
+        int pokeexpire;                 /*!<  When to expire poke (qualify= checking) */
+        int lastms;                     /*!<  How long last response took (in ms), or -1 for no response */
+        int maxms;                      /*!<  Max ms we will accept for the host to be up, 0 to not monitor */
+        struct timeval ps;              /*!<  Ping send time */
+
+        struct sockaddr_in defaddr;     /*!<  Default IP address, used until registration */
+        struct ast_ha *ha;              /*!<  Access control list */
+        struct ast_variable *chanvars;  /*!<  Variables to set for channel created by user */
+        struct sip_pvt *mwipvt;         /*!<  Subscription for MWI */
+        int lastmsg;
+        int autoframing;
+};
+/*! \brief States for outbound registrations (with register= lines in sip.conf */
+enum sipregistrystate {
+        REG_STATE_UNREGISTERED = 0,     /*!< We are not registred */
+        REG_STATE_REGSENT,      /*!< Registration request sent */
+        REG_STATE_AUTHSENT,     /*!< We have tried to authenticate */
+        REG_STATE_REGISTERED,   /*!< Registred and done */
+        REG_STATE_REJECTED,     /*!< Registration rejected */
+        REG_STATE_TIMEOUT,      /*!< Registration timed out */
+        REG_STATE_NOAUTH,       /*!< We have no accepted credentials */
+        REG_STATE_FAILED,       /*!< Registration failed after several tries */
+};
+
+/*! \brief Registrations with other SIP proxies */
+struct sip_registry {
+        ASTOBJ_COMPONENTS_FULL(struct sip_registry,1,1);
+        AST_DECLARE_STRING_FIELDS(
+                AST_STRING_FIELD(callid);       /*!< Global Call-ID */
+                AST_STRING_FIELD(realm);        /*!< Authorization realm */
+                AST_STRING_FIELD(nonce);        /*!< Authorization nonce */
+                AST_STRING_FIELD(opaque);       /*!< Opaque nonsense */
+                AST_STRING_FIELD(qop);          /*!< Quality of Protection, since SIP wasn't complicated enough yet. */
+                AST_STRING_FIELD(domain);       /*!< Authorization domain */
+                AST_STRING_FIELD(username);     /*!< Who we are registering as */
+                AST_STRING_FIELD(authuser);     /*!< Who we *authenticate* as */
+                AST_STRING_FIELD(hostname);     /*!< Domain or host we register to */
+                AST_STRING_FIELD(secret);       /*!< Password in clear text */
+                AST_STRING_FIELD(md5secret);    /*!< Password in md5 */
+                AST_STRING_FIELD(contact);      /*!< Contact extension */
+                AST_STRING_FIELD(random);
+        );
+        int portno;                     /*!<  Optional port override */
+        int expire;                     /*!< Sched ID of expiration */
+        int regattempts;                /*!< Number of attempts (since the last success) */
+        int timeout;                    /*!< sched id of sip_reg_timeout */
+        int refresh;                    /*!< How often to refresh */
+        struct sip_pvt *call;           /*!< create a sip_pvt structure for each outbound "registration dialog" in progress */
+        enum sipregistrystate regstate; /*!< Registration state (see above) */
+        time_t regtime;         /*!< Last succesful registration time */
+        int callid_valid;               /*!< 0 means we haven't chosen callid for this registry yet. */
+        unsigned int ocseq;             /*!< Sequence number we got to for REGISTERs for this registry */
+        struct sockaddr_in us;          /*!< Who the server thinks we are */
+        int noncecount;                 /*!< Nonce-count */
+        char lastmsg[256];              /*!< Last Message sent/received */
+};
+
+/*! \brief Authentication result from check_auth* functions */
+enum check_auth_result {
+        AUTH_SUCCESSFUL = 0,
+        AUTH_CHALLENGE_SENT = 1,
+        AUTH_SECRET_FAILED = -1,
+        AUTH_USERNAME_MISMATCH = -2,
+        AUTH_NOT_FOUND = -3,
+        AUTH_FAKE_AUTH = -4,
+        AUTH_UNKNOWN_DOMAIN = -5,
+        AUTH_PEER_NOT_DYNAMIC = -6,
+        AUTH_ACL_FAILED = -7,
+};
diff --git a/main/channel.c b/main/channel.c
index fccc364..bb4a3e0 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -69,6 +69,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision: 95024 $")
 #include "asterisk/sha1.h"
 #include "asterisk/threadstorage.h"
 #include "asterisk/slinfactory.h"
+#include "asterisk/sip_def.h"
 
 struct channel_spy_trans {
 	int last_format;
@@ -3394,8 +3395,15 @@ int ast_channel_sendurl(struct ast_channel *chan, const char *url)
 
 int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
 {
+	int transcode_order[] = {AST_FORMAT_GSM, AST_FORMAT_ALAW, AST_FORMAT_ULAW, AST_FORMAT_ADPCM, AST_FORMAT_G726, AST_FORMAT_ILBC, AST_FORMAT_LPC10};
+	int transcode_order_index[] = {2, 4, 3, 6, 5, 11, 8};
+	int codec_preflist[] = {AST_FORMAT_G729A, AST_FORMAT_G723_1, AST_FORMAT_GSM, AST_FORMAT_G726, AST_FORMAT_ALAW, AST_FORMAT_ULAW, AST_FORMAT_ADPCM, AST_FORMAT_ILBC, AST_FORMAT_LPC10};
+	int codec_preflist_index[] = {9, 1, 2, 5, 4, 3, 6, 11, 8};
+
 	int src;
 	int dst;
+	int index = 0;
+	char buf[BUFSIZ];
 
 	if (chan->readformat == peer->writeformat && chan->writeformat == peer->readformat) {
 		/* Already compatible!  Moving on ... */
@@ -3405,6 +3413,151 @@ int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *pe
 	/* Set up translation from the chan to the peer */
 	src = chan->nativeformats;
 	dst = peer->nativeformats;
+	
+	if ((strcmp(chan->tech->type, peer->tech->type) == 0) && (strcmp(chan->tech->type, "SIP") == 0))
+	{
+	        /* load codec info and try to make channels compatible */
+		struct ast_format_list *afl;
+		struct sip_pvt *src_pvt = chan->tech_pvt;
+	        struct sip_pvt *dst_pvt = peer->tech_pvt;
+	
+		if (option_debug) {
+			ast_log(LOG_DEBUG, "Making peers compatible: SRC username = %s, DST username = %s\n", src_pvt->username, dst_pvt->username);
+		        ast_log(LOG_DEBUG, "SIP user %s capability is %s\n", src_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, src_pvt->capability));
+		        ast_log(LOG_DEBUG, "SIP user %s capability is %s\n", dst_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, dst_pvt->capability));
+		        ast_log(LOG_DEBUG, "SIP user %s pre-nativeformats %s\n", src_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, src));
+		        ast_log(LOG_DEBUG, "SIP user %s pre-nativeformats %s\n", dst_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, dst));
+		}        
+		/* fix jointcapability */
+		src_pvt->jointcapability = dst_pvt->jointcapability = src_pvt->capability & dst_pvt->capability;
+		src_pvt->peercapability = dst_pvt->capability;
+		dst_pvt->peercapability = src_pvt->capability;
+	        
+		if (src_pvt->jointcapability) {
+			if (option_debug) ast_log(LOG_DEBUG, "Users' jointcapability is %s\n", 
+				ast_getformatname_multiple(buf, BUFSIZ, src_pvt->jointcapability));
+		
+		        chan->nativeformats = peer->nativeformats = 0;
+		
+			while (!chan->nativeformats && index < (sizeof(codec_preflist)/sizeof(codec_preflist[0]))) {
+		                chan->nativeformats = peer->nativeformats = src_pvt->jointcapability & codec_preflist[index];
+		                index++;
+		        }
+			if (option_debug) ast_log(LOG_DEBUG, "Chan/Peer (%s/%s) nativeformats %s\n", src_pvt->username, dst_pvt->username,
+				ast_getformatname_multiple(buf, BUFSIZ, chan->nativeformats));
+		        
+			chan->readformat = chan->rawreadformat = chan->writeformat = chan->rawwriteformat =\
+				                   peer->readformat = peer->rawreadformat = peer->writeformat = peer->rawwriteformat = chan->nativeformats;
+		
+		        ast_set_read_format(chan, chan->nativeformats);
+		        ast_set_write_format(chan, chan->nativeformats);
+		        ast_set_read_format(peer, peer->nativeformats);
+		        ast_set_write_format(peer, peer->nativeformats);
+		
+			int foo = 0;
+			for (index = 0; index < 32; index++) {
+				src_pvt->prefs.order[index] = 0;
+				src_pvt->prefs.framing[index] = 0;
+				dst_pvt->prefs.order[index] = 0;
+				dst_pvt->prefs.framing[index] = 0;
+			}
+		
+			for (index = 0; index < (sizeof(codec_preflist)/sizeof(codec_preflist[0])); index++) {
+				if (src_pvt->jointcapability & codec_preflist[index]) {
+					src_pvt->prefs.order[foo] = dst_pvt->prefs.order[foo] = codec_preflist_index[index];
+					foo++;
+				}
+			}
+			if (option_debug) {
+				ast_log(LOG_DEBUG, "Codec prefs for user %s: ", src_pvt->username);
+				for (index = 0; index < 32; index++) {
+					afl = ast_get_format_list_index(src_pvt->prefs.order[index] - 1);
+					if (src_pvt->prefs.order[index]) printf("%s ", afl->name);
+				}
+				printf("\n");
+				ast_log(LOG_DEBUG, "Codec prefs for user %s: ", dst_pvt->username);
+				for (index = 0; index < 32; index++) {
+					afl = ast_get_format_list_index(dst_pvt->prefs.order[index] - 1);
+					if (dst_pvt->prefs.order[index]) printf("%s ", afl->name);
+				}
+				printf("\n");
+			}
+		
+			if (option_debug) ast_log(LOG_DEBUG, "Made channels %s and %s compatible\n", chan->name, peer->name);	
+			
+			return 0; 
+		}
+		else {
+			if (option_debug) ast_log(LOG_DEBUG, "Jointcapability = 0. Running codec translator...\n");
+
+		        chan->nativeformats = peer->nativeformats = 0;
+			index = 0;
+			while (!chan->nativeformats && index < sizeof(transcode_order)/sizeof(transcode_order[0])) {
+				chan->nativeformats = src_pvt->capability & transcode_order[index];
+				index++;
+		        }
+			
+			index = 0;
+			while (!peer->nativeformats && index < sizeof(transcode_order)/sizeof(transcode_order[0])) {
+				peer->nativeformats = dst_pvt->capability & transcode_order[index];
+			        index++;
+		        }
+		       	if (option_debug) { 
+				ast_log(LOG_DEBUG, "SIP user %s nativeformats %s\n", src_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, src));
+			        ast_log(LOG_DEBUG, "SIP user %s nativeformats %s\n", dst_pvt->username, ast_getformatname_multiple(buf, BUFSIZ, dst));
+			}
+
+		        chan->readformat = chan->rawreadformat = chan->writeformat = chan->rawwriteformat = chan->nativeformats;
+		        peer->readformat = peer->rawreadformat = peer->writeformat = peer->rawwriteformat = peer->nativeformats;
+		        
+			ast_set_read_format(chan, chan->nativeformats);
+		        ast_set_write_format(chan, chan->nativeformats);
+		        ast_set_read_format(peer, peer->nativeformats);
+		        ast_set_write_format(peer, peer->nativeformats);
+			
+			int foo = 0;
+			for (index = 0; index < 32; index++) {
+				src_pvt->prefs.order[index] = 0;
+				src_pvt->prefs.framing[index] = 0;
+				dst_pvt->prefs.order[index] = 0;
+				dst_pvt->prefs.framing[index] = 0;
+			}
+		
+			for (index = 0; index < sizeof(transcode_order)/sizeof(transcode_order[0]); index++) {
+				if (src_pvt->capability & transcode_order[index]) {
+					src_pvt->prefs.order[foo] = transcode_order_index[index];
+					foo++;
+				}
+			}
+			foo = 0;
+			
+			for (index = 0; index < sizeof(transcode_order)/sizeof(transcode_order[0]); index++) {
+				if (dst_pvt->capability & transcode_order[index]) {
+					dst_pvt->prefs.order[foo] = transcode_order_index[index];
+					foo++;
+				}
+			}
+
+			if (option_debug) {
+				ast_log(LOG_DEBUG, "Codec prefs for user %s: ", src_pvt->username);
+				for (index = 0; index < 32; index++) {
+					afl = ast_get_format_list_index(src_pvt->prefs.order[index] - 1);
+					if (src_pvt->prefs.order[index]) printf("%s ", afl->name);
+				}
+				printf("\n");
+				ast_log(LOG_DEBUG, "Codec prefs for user %s: ", dst_pvt->username);
+				for (index = 0; index < 32; index++) {
+					afl = ast_get_format_list_index(dst_pvt->prefs.order[index] - 1);
+					if (dst_pvt->prefs.order[index]) printf("%s ", afl->name);
+				}
+				printf("\n");
+			}
+		
+			src = chan->nativeformats;
+			dst = peer->nativeformats;
+		}
+	}
+	
 	if (ast_translator_best_choice(&dst, &src) < 0) {
 		ast_log(LOG_WARNING, "No path to translate from %s(%d) to %s(%d)\n", chan->name, src, peer->name, dst);
 		return -1;
