diff --git a/openbsc/include/openbsc/mgcp.h b/openbsc/include/openbsc/mgcp.h
index b2262bc..a216547 100644
--- a/openbsc/include/openbsc/mgcp.h
+++ b/openbsc/include/openbsc/mgcp.h
@@ -1,8 +1,8 @@
 /* A Media Gateway Control Protocol Media Gateway: RFC 3435 */
 
 /*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -69,6 +69,7 @@ struct mgcp_endpoint;
 struct mgcp_config;
 struct mgcp_trunk_config;
 struct mgcp_rtp_end;
+struct mgcp_transcoding;
 
 #define MGCP_ENDP_CRCX 1
 #define MGCP_ENDP_DLCX 2
@@ -158,6 +159,9 @@ struct mgcp_trunk_config {
 	/* spec handling */
 	int force_realloc;
 
+	/* transcoding */
+	const struct mgcp_transcoding *transcoder;
+
 	/* timer */
 	struct osmo_timer_list keepalive_timer;
 
@@ -184,12 +188,6 @@ struct mgcp_config {
 	struct in_addr transcoder_in;
 	int transcoder_remote_base;
 
-	/* RTP processing */
-	mgcp_processing rtp_processing_cb;
-	mgcp_processing_setup setup_rtp_processing_cb;
-
-	mgcp_get_format get_net_downlink_format_cb;
-
 	struct osmo_wqueue gw_fd;
 
 	struct mgcp_port_range bts_ports;
diff --git a/openbsc/include/openbsc/mgcp_internal.h b/openbsc/include/openbsc/mgcp_internal.h
index 7c89d10..a62dbb2 100644
--- a/openbsc/include/openbsc/mgcp_internal.h
+++ b/openbsc/include/openbsc/mgcp_internal.h
@@ -1,8 +1,8 @@
 /* MGCP Private Data */
 
 /*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -150,6 +150,17 @@ enum mgcp_type {
 	MGCP_OSMUX_BSC_NAT,
 };
 
+/**
+ * Function pointers for RTP processing/transcoding
+ */
+struct mgcp_transcoding {
+	mgcp_processing processing_cb;
+	mgcp_processing_setup setup_processing_cb;
+	mgcp_get_format get_net_downlink_format_cb;
+};
+
+extern const struct mgcp_transcoding *mgcp_default_transcoder;
+
 #include <openbsc/osmux.h>
 
 struct mgcp_endpoint {
diff --git a/openbsc/include/openbsc/mgcp_transcode.h b/openbsc/include/openbsc/mgcp_transcode.h
index 147e48b..02b039d 100644
--- a/openbsc/include/openbsc/mgcp_transcode.h
+++ b/openbsc/include/openbsc/mgcp_transcode.h
@@ -37,6 +37,8 @@ enum audio_format {
 	AF_PCMU
 };
 
+struct mgcp_transcoding;
+extern const struct mgcp_transcoding mgcp_sw_transcoder;
 
 struct mgcp_process_rtp_state {
 	/* decoding */
diff --git a/openbsc/src/libmgcp/mgcp_network.c b/openbsc/src/libmgcp/mgcp_network.c
index abce6e4..e4f5f7d 100644
--- a/openbsc/src/libmgcp/mgcp_network.c
+++ b/openbsc/src/libmgcp/mgcp_network.c
@@ -584,6 +584,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
 	      struct sockaddr_in *addr, char *buf, int rc)
 {
 	struct mgcp_trunk_config *tcfg = endp->tcfg;
+	const struct mgcp_transcoding *trans = tcfg->transcoder;
 	struct mgcp_rtp_end *rtp_end;
 	struct mgcp_rtp_state *rtp_state;
 	int tap_idx;
@@ -613,7 +614,7 @@ int mgcp_send(struct mgcp_endpoint *endp, int dest, int is_rtp,
 		int nbytes = 0;
 		int len = rc;
 		do {
-			cont = endp->cfg->rtp_processing_cb(endp, rtp_end,
+			cont = trans->processing_cb(endp, rtp_end,
 							buf, &len, RTP_BUF_SIZE);
 			if (cont < 0)
 				break;
diff --git a/openbsc/src/libmgcp/mgcp_protocol.c b/openbsc/src/libmgcp/mgcp_protocol.c
index 1819cea..8017fe8 100644
--- a/openbsc/src/libmgcp/mgcp_protocol.c
+++ b/openbsc/src/libmgcp/mgcp_protocol.c
@@ -2,8 +2,8 @@
 /* The protocol implementation */
 
 /*
- * (C) 2009-2012 by Holger Hans Peter Freyther <zecke@selfish.org>
- * (C) 2009-2012 by On-Waves
+ * (C) 2009-2016 by Holger Hans Peter Freyther <zecke@selfish.org>
+ * (C) 2009-2016 by On-Waves
  * All Rights Reserved
  *
  * This program is free software; you can redistribute it and/or modify
@@ -66,6 +66,14 @@ static int setup_rtp_processing(struct mgcp_endpoint *endp);
 
 static int mgcp_analyze_header(struct mgcp_parse_data *parse, char *data);
 
+static const struct mgcp_transcoding no_transcoder = {
+	.processing_cb = &mgcp_rtp_processing_default,
+	.setup_processing_cb = &mgcp_setup_rtp_processing_default,
+	.get_net_downlink_format_cb = &mgcp_get_net_downlink_format_default,
+};
+
+const struct mgcp_transcoding *mgcp_default_transcoder = &no_transcoder;
+
 static int mgcp_check_param(const struct mgcp_endpoint *endp, const char *line)
 {
 	const size_t line_len = strlen(line);
@@ -197,13 +205,15 @@ static struct msgb *create_err_response(struct mgcp_endpoint *endp,
 static int write_response_sdp(struct mgcp_endpoint *endp,
 			      char *sdp_record, size_t size, const char *addr)
 {
+	const struct mgcp_transcoding *trans;
 	const char *fmtp_extra;
 	const char *audio_name;
 	int payload_type;
 	int len;
 	int nchars;
 
-	endp->cfg->get_net_downlink_format_cb(endp, &payload_type,
+	trans = endp->tcfg->transcoder;
+	trans->get_net_downlink_format_cb(endp, &payload_type,
 					      &audio_name, &fmtp_extra);
 
 	len = snprintf(sdp_record, size,
@@ -1200,12 +1210,8 @@ struct mgcp_config *mgcp_config_alloc(void)
 	cfg->bts_ports.base_port = RTP_PORT_DEFAULT;
 	cfg->net_ports.base_port = RTP_PORT_NET_DEFAULT;
 
-	cfg->rtp_processing_cb = &mgcp_rtp_processing_default;
-	cfg->setup_rtp_processing_cb = &mgcp_setup_rtp_processing_default;
-
-	cfg->get_net_downlink_format_cb = &mgcp_get_net_downlink_format_default;
-
 	/* default trunk handling */
+	cfg->trunk.transcoder = mgcp_default_transcoder;
 	cfg->trunk.cfg = cfg;
 	cfg->trunk.trunk_nr = 0;
 	cfg->trunk.trunk_type = MGCP_TRUNK_VIRTUAL;
@@ -1231,6 +1237,7 @@ struct mgcp_trunk_config *mgcp_trunk_alloc(struct mgcp_config *cfg, int nr)
 		return NULL;
 	}
 
+	trunk->transcoder = mgcp_default_transcoder;
 	trunk->cfg = cfg;
 	trunk->trunk_type = MGCP_TRUNK_E1;
 	trunk->trunk_nr = nr;
@@ -1459,7 +1466,7 @@ int mgcp_send_reset_ep(struct mgcp_endpoint *endp, int endpoint)
 static int setup_rtp_processing(struct mgcp_endpoint *endp)
 {
 	int rc = 0;
-	struct mgcp_config *cfg = endp->cfg;
+	const struct mgcp_transcoding *trans = endp->tcfg->transcoder;
 
 	if (endp->type != MGCP_RTP_DEFAULT)
 		return 0;
@@ -1468,14 +1475,14 @@ static int setup_rtp_processing(struct mgcp_endpoint *endp)
 		return 0;
 
 	if (endp->conn_mode & MGCP_CONN_SEND_ONLY)
-		rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end);
+		rc |= trans->setup_processing_cb(endp, &endp->net_end, &endp->bts_end);
 	else
-		rc |= cfg->setup_rtp_processing_cb(endp, &endp->net_end, NULL);
+		rc |= trans->setup_processing_cb(endp, &endp->net_end, NULL);
 
 	if (endp->conn_mode & MGCP_CONN_RECV_ONLY)
-		rc |= cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end);
+		rc |= trans->setup_processing_cb(endp, &endp->bts_end, &endp->net_end);
 	else
-		rc |= cfg->setup_rtp_processing_cb(endp, &endp->bts_end, NULL);
+		rc |= trans->setup_processing_cb(endp, &endp->bts_end, NULL);
 	return rc;
 }
 
diff --git a/openbsc/src/libmgcp/mgcp_transcode.c b/openbsc/src/libmgcp/mgcp_transcode.c
index c994d32..aaa8863 100644
--- a/openbsc/src/libmgcp/mgcp_transcode.c
+++ b/openbsc/src/libmgcp/mgcp_transcode.c
@@ -32,6 +32,12 @@
 #include <osmocom/core/talloc.h>
 #include <osmocom/netif/rtp.h>
 
+const struct mgcp_transcoding mgcp_sw_transcoder = {
+	.processing_cb = mgcp_transcoding_process_rtp,
+	.setup_processing_cb = mgcp_transcoding_setup,
+	.get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format,
+};
+
 int mgcp_transcoding_get_frame_size(void *state_, int nsamples, int dst)
 {
 	struct mgcp_process_rtp_state *state = state_;
@@ -470,12 +476,12 @@ struct mgcp_process_rtp_state *check_transcode_state(
 		goto done;
 	/* The matching alternate payload type? Then switch */
 	if (rtp_hdr->payload_type == src_end->alt_codec.payload_type) {
-		struct mgcp_config *cfg = endp->cfg;
+		const struct mgcp_transcoding *trans = endp->tcfg->transcoder;
 		struct mgcp_rtp_codec tmp_codec = src_end->alt_codec;
 		src_end->alt_codec = src_end->codec;
 		src_end->codec = tmp_codec;
-		cfg->setup_rtp_processing_cb(endp, &endp->net_end, &endp->bts_end);
-		cfg->setup_rtp_processing_cb(endp, &endp->bts_end, &endp->net_end);
+		trans->setup_processing_cb(endp, &endp->net_end, &endp->bts_end);
+		trans->setup_processing_cb(endp, &endp->bts_end, &endp->net_end);
 	}
 
 done:
diff --git a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
index e226b02..3c968be 100644
--- a/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
+++ b/openbsc/src/osmo-bsc_mgcp/mgcp_main.c
@@ -207,16 +207,14 @@ int main(int argc, char **argv)
 	osmo_init_ignore_signals();
 	osmo_init_logging(&log_info);
 
+#ifdef BUILD_MGCP_TRANSCODING
+	mgcp_default_transcoder = &mgcp_sw_transcoder;
+#endif
+
 	cfg = mgcp_config_alloc();
 	if (!cfg)
 		return -1;
 
-#ifdef BUILD_MGCP_TRANSCODING
-	cfg->setup_rtp_processing_cb = &mgcp_transcoding_setup;
-	cfg->rtp_processing_cb = &mgcp_transcoding_process_rtp;
-	cfg->get_net_downlink_format_cb = &mgcp_transcoding_net_downlink_format;
-#endif
-
 	vty_info.copyright = openbsc_copyright;
 	vty_init(&vty_info);
 	logging_vty_add_cmds(&log_info);
diff --git a/openbsc/tests/mgcp/mgcp_transcoding_test.c b/openbsc/tests/mgcp/mgcp_transcoding_test.c
index c5c0a0b..72c75eb 100644
--- a/openbsc/tests/mgcp/mgcp_transcoding_test.c
+++ b/openbsc/tests/mgcp/mgcp_transcoding_test.c
@@ -161,6 +161,12 @@ static int audio_name_to_type(const char *name)
 
 int mgcp_get_trans_frame_size(void *state_, int nsamples, int dst);
 
+static const struct mgcp_transcoding test_transcoder = {
+	.setup_processing_cb = mgcp_transcoding_setup,
+	.processing_cb = mgcp_transcoding_process_rtp,
+	.get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format,
+};
+
 static int given_configured_endpoint(int in_samples, int out_samples,
 				const char *srcfmt, const char *dstfmt,
 				void **out_ctx, struct mgcp_endpoint **out_endp)
@@ -176,10 +182,7 @@ static int given_configured_endpoint(int in_samples, int out_samples,
 	tcfg = talloc_zero(cfg, struct mgcp_trunk_config);
 	endp = talloc_zero(tcfg, struct mgcp_endpoint);
 
-	cfg->setup_rtp_processing_cb = mgcp_transcoding_setup;
-	cfg->rtp_processing_cb = mgcp_transcoding_process_rtp;
-	cfg->get_net_downlink_format_cb = mgcp_transcoding_net_downlink_format;
-
+	tcfg->transcoder = &test_transcoder;
 	tcfg->endpoints = endp;
 	tcfg->number_endpoints = 1;
 	tcfg->cfg = cfg;
