diff --git a/CHANGES b/CHANGES
index 5720883ab7d8c17afe1e48ef12de2ecf0626950d..5d14c97d176bb86d5ec3ad5e36ed6e72f7d5ed7f 100644
--- a/CHANGES
+++ b/CHANGES
@@ -62,6 +62,11 @@ RTP
    when you use more than 32 formats and calls are not accepted by a remote
    implementation, please report this and go back to rtp_pt_dynamic = 96.
 
+ * A new setting, "rtp_use_dynamic", has been added in asterisk.conf". When set
+   to "yes" RTP dynamic payload types are assigned dynamically per RTP instance.
+   When set to "no" RTP dynamic payload types are globally initialized to pre-
+   designated numbers and function similar to static payload types.
+
 app_originate
 ------------------
  * Added support to gosub predial routines on both original channel and on the
diff --git a/configs/samples/asterisk.conf.sample b/configs/samples/asterisk.conf.sample
index e13a944b06ac029aae04e4a1fbd4b9f73326703b..30934e4a9978dada3e37e63fdaae3b13981b7f3b 100644
--- a/configs/samples/asterisk.conf.sample
+++ b/configs/samples/asterisk.conf.sample
@@ -97,6 +97,10 @@ documentation_language = en_US	; Set the language you want documentation
 				; This is currently is used by DUNDi and
 				; Exchanging Device and Mailbox State
 				; using protocols: XMPP, Corosync and PJSIP.
+;rtp_use_dynamic = yes          ; When set to "yes" RTP dynamic payload types
+                                ; are assigned dynamically per RTP instance vs.
+                                ; allowing Asterisk to globally initialize them
+                                ; to pre-designated numbers (defaults to "yes").
 ;rtp_pt_dynamic = 35		; Normally the Dynamic RTP Payload Type numbers
 				; are 96-127, which allow just 32 formats. The
 				; starting point 35 enables the range 35-63 and
diff --git a/include/asterisk/options.h b/include/asterisk/options.h
index 05ad6c56010c88e2bb0fbe9b08976c6dd0709529..0a20f10a8dd5b93a79e0c75ff96e451c8bd62370 100644
--- a/include/asterisk/options.h
+++ b/include/asterisk/options.h
@@ -196,6 +196,7 @@ extern int dahdi_chan_name_len;
 
 extern int ast_language_is_prefix;
 
+extern int ast_option_rtpusedynamic;
 extern unsigned int ast_option_rtpptdynamic;
 
 #if defined(__cplusplus) || defined(c_plusplus)
diff --git a/main/asterisk.c b/main/asterisk.c
index 69183c1f39082ce9fec6fad1962db4c3ae98aa99..68859ab2fad40edcf248396a24779985648d1612 100644
--- a/main/asterisk.c
+++ b/main/asterisk.c
@@ -339,6 +339,7 @@ unsigned int option_dtmfminduration;		/*!< Minimum duration of DTMF. */
 #if defined(HAVE_SYSINFO)
 long option_minmemfree;				/*!< Minimum amount of free system memory - stop accepting calls if free memory falls below this watermark */
 #endif
+int ast_option_rtpusedynamic;
 unsigned int ast_option_rtpptdynamic;
 
 /*! @} */
@@ -602,6 +603,7 @@ static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_c
 	ast_cli(a->fd, "  Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled");
 	ast_cli(a->fd, "  Generic PLC:                 %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled");
 	ast_cli(a->fd, "  Min DTMF duration::          %u\n", option_dtmfminduration);
+	ast_cli(a->fd, "  RTP use dynamic payloads:    %u\n", ast_option_rtpusedynamic);
 
 	if (ast_option_rtpptdynamic == AST_RTP_PT_LAST_REASSIGN) {
 		ast_cli(a->fd, "  RTP dynamic payload types:   %u,%u-%u\n",
@@ -3499,6 +3501,7 @@ static void ast_readconfig(void)
 
 	/* Set default value */
 	option_dtmfminduration = AST_MIN_DTMF_DURATION;
+	ast_option_rtpusedynamic = 1;
 	ast_option_rtpptdynamic = 35;
 
 	/* init with buildtime config */
@@ -3655,6 +3658,8 @@ static void ast_readconfig(void)
 			if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) {
 				option_dtmfminduration = AST_MIN_DTMF_DURATION;
 			}
+		} else if (!strcasecmp(v->name, "rtp_use_dynamic")) {
+			ast_option_rtpusedynamic = ast_true(v->value);
 		/* http://www.iana.org/assignments/rtp-parameters
 		 * RTP dynamic payload types start at 96 normally; extend down to 0 */
 		} else if (!strcasecmp(v->name, "rtp_pt_dynamic")) {
diff --git a/main/rtp_engine.c b/main/rtp_engine.c
index 931f89d7cad9810a32368569d4e1b629c2459ef5..00f9d595fccea87fc991611259759a4bc05b2c25 100644
--- a/main/rtp_engine.c
+++ b/main/rtp_engine.c
@@ -266,14 +266,28 @@ static void rtp_payload_type_dtor(void *obj)
 	ao2_cleanup(payload->format);
 }
 
-struct ast_rtp_payload_type *ast_rtp_engine_alloc_payload_type(void)
+static struct ast_rtp_payload_type *rtp_payload_type_alloc(struct ast_format *format,
+	int payload, int rtp_code, int primary_mapping)
 {
-	struct ast_rtp_payload_type *payload;
+	struct ast_rtp_payload_type *type = ao2_alloc_options(
+		sizeof(*type), rtp_payload_type_dtor, AO2_ALLOC_OPT_LOCK_NOLOCK);
 
-	payload = ao2_alloc_options(sizeof(*payload), rtp_payload_type_dtor,
-		AO2_ALLOC_OPT_LOCK_NOLOCK);
+	if (!type) {
+		return NULL;
+	}
 
-	return payload;
+	type->format = ao2_bump(format);
+	type->asterisk_format = type->format != NULL;
+	type->payload = payload;
+	type->rtp_code = rtp_code;
+	type->primary_mapping = primary_mapping;
+
+	return type;
+}
+
+struct ast_rtp_payload_type *ast_rtp_engine_alloc_payload_type(void)
+{
+	return rtp_payload_type_alloc(NULL, 0, 0, 0);
 }
 
 int ast_rtp_engine_register2(struct ast_rtp_engine *engine, struct ast_module *module)
@@ -1250,31 +1264,112 @@ static int find_static_payload_type(int asterisk_format, const struct ast_format
 
 /*!
  * \internal
- * \brief Find the first unused dynamic rx payload type.
- * \since 14.0.0
+ * \brief Find the first unused payload type in a given range
  *
- * \param codecs Codecs structure to look in
+ * \param codecs The codec structure to look in
+ * \param start Starting index
+ * \param end Ending index
+ * \param ignore Skip these payloads types
  *
- * \note It is assumed that codecs is at least read locked before calling.
+ * \note The static_RTP_PT_lock object must be locked before calling
  *
  * \retval Numerical payload type
  * \retval -1 if not found.
  */
-static int rtp_codecs_find_empty_dynamic_rx(struct ast_rtp_codecs *codecs)
+static int find_unused_payload_in_range(const struct ast_rtp_codecs *codecs,
+		int start, int end, struct ast_rtp_payload_type *ignore[])
 {
-	struct ast_rtp_payload_type *type;
-	int idx;
-	int payload = -1;
+	int x;
 
-	idx = AST_RTP_PT_FIRST_DYNAMIC;
-	for (; idx < AST_VECTOR_SIZE(&codecs->payload_mapping_rx); ++idx) {
-		type = AST_VECTOR_GET(&codecs->payload_mapping_rx, idx);
+	for (x = start; x < end; ++x) {
+		struct ast_rtp_payload_type *type;
+
+		if (ignore[x]) {
+			continue;
+		} else if (!codecs || x >= AST_VECTOR_SIZE(&codecs->payload_mapping_rx)) {
+			return x;
+		}
+
+		type = AST_VECTOR_GET(&codecs->payload_mapping_rx, x);
 		if (!type) {
-			payload = idx;
-			break;
+			return x;
 		}
 	}
-	return payload;
+	return -1;
+}
+
+/*!
+ * \internal
+ * \brief Find an unused payload type
+ *
+ * \param codecs Codecs structure to look in
+ *
+ * \note Both static_RTP_PT_lock and codecs (if given) must be at least
+ *       read locked before calling.
+ *
+ * \retval Numerical payload type
+ * \retval -1 if not found.
+ */
+static int find_unused_payload(const struct ast_rtp_codecs *codecs)
+{
+	int res;
+
+	/* find next available dynamic payload slot */
+	res = find_unused_payload_in_range(
+		codecs, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT, static_RTP_PT);
+	if (res != -1) {
+		return res;
+	}
+
+	if (ast_option_rtpusedynamic) {
+		/*
+		 * We're using default values for some dynamic types. So if an unused
+		 * slot was not found try again, but this time ignore the default
+		 * values declared for dynamic types (except for 101 and 121) .
+		 */
+		static struct ast_rtp_payload_type *ignore[AST_RTP_MAX_PT] = {0};
+
+		ignore[101] = static_RTP_PT[101];
+		ignore[121] = static_RTP_PT[121];
+
+		res = find_unused_payload_in_range(
+			codecs, AST_RTP_PT_FIRST_DYNAMIC, AST_RTP_MAX_PT, ignore);
+		if (res != -1) {
+			return res;
+		}
+	}
+
+	/* http://www.iana.org/assignments/rtp-parameters
+	 * RFC 3551, Section 3: "[...] applications which need to define more
+	 * than 32 dynamic payload types MAY bind codes below 96, in which case
+	 * it is RECOMMENDED that unassigned payload type numbers be used
+	 * first". Updated by RFC 5761, Section 4: "[...] values in the range
+	 * 64-95 MUST NOT be used [to avoid conflicts with RTCP]". Summaries:
+	 * https://tools.ietf.org/html/draft-roach-mmusic-unified-plan#section-3.2.1.2
+	 * https://tools.ietf.org/html/draft-wu-avtcore-dynamic-pt-usage#section-3
+	 */
+	res = find_unused_payload_in_range(codecs, MAX(ast_option_rtpptdynamic, 35),
+		AST_RTP_PT_LAST_REASSIGN, static_RTP_PT);
+	if (res != -1) {
+		return res;
+	}
+
+	/* Yet, reusing mappings below 35 is not supported in Asterisk because
+	 * when Compact Headers are activated, no rtpmap is send for those below
+	 * 35. If you want to use 35 and below
+	 * A) do not use Compact Headers,
+	 * B) remove that code in chan_sip/res_pjsip, or
+	 * C) add a flag that this RTP Payload Type got reassigned dynamically
+	 *    and requires a rtpmap even with Compact Headers enabled.
+	 */
+	res = find_unused_payload_in_range(
+		codecs, MAX(ast_option_rtpptdynamic, 20), 35, static_RTP_PT);
+	if (res != -1) {
+		return res;
+	}
+
+	return find_unused_payload_in_range(
+		codecs, MAX(ast_option_rtpptdynamic, 0), 20, static_RTP_PT);
 }
 
 /*!
@@ -1331,30 +1426,26 @@ static int rtp_codecs_assign_payload_code_rx(struct ast_rtp_codecs *codecs, int
 	struct ast_rtp_payload_type *new_type;
 
 	payload = find_static_payload_type(asterisk_format, format, code);
-	if (payload < 0) {
+
+	if (payload < 0 && (!asterisk_format || ast_option_rtpusedynamic)) {
 		return payload;
 	}
 
-	new_type = ast_rtp_engine_alloc_payload_type();
+	new_type = rtp_payload_type_alloc(format, payload, code, 1);
 	if (!new_type) {
 		return -1;
 	}
-	new_type->format = ao2_bump(format);
-	new_type->asterisk_format = asterisk_format;
-	new_type->rtp_code = code;
-	new_type->payload = payload;
-	new_type->primary_mapping = 1;
 
 	ast_rwlock_wrlock(&codecs->codecs_lock);
-	if (payload < AST_RTP_PT_FIRST_DYNAMIC
+	if (payload > -1 && (payload < AST_RTP_PT_FIRST_DYNAMIC
 		|| AST_VECTOR_SIZE(&codecs->payload_mapping_rx) <= payload
-		|| !AST_VECTOR_GET(&codecs->payload_mapping_rx, payload)) {
+		|| !AST_VECTOR_GET(&codecs->payload_mapping_rx, payload))) {
 		/*
 		 * The payload type is a static assignment
 		 * or our default dynamic position is available.
 		 */
-		rtp_codecs_payload_replace_rx(codecs, payload, new_type);
-	} else if (-1 < (payload = rtp_codecs_find_empty_dynamic_rx(codecs))
+               rtp_codecs_payload_replace_rx(codecs, payload, new_type);
+	} else if (-1 < (payload = find_unused_payload(codecs))
 		|| -1 < (payload = rtp_codecs_find_non_primary_dynamic_rx(codecs))) {
 		/*
 		 * We found the first available empty dynamic position
@@ -1370,7 +1461,8 @@ static int rtp_codecs_assign_payload_code_rx(struct ast_rtp_codecs *codecs, int
 		 *
 		 * I don't think this is really possible.
 		 */
-		ast_log(LOG_WARNING, "No dynamic RTP payload type values available!\n");
+		ast_log(LOG_WARNING, "No dynamic RTP payload type values available "
+			"for %s - %d!\n", format ? ast_format_get_name(format) : "", code);
 	}
 	ast_rwlock_unlock(&codecs->codecs_lock);
 
@@ -2293,95 +2385,47 @@ static void set_next_mime_type(struct ast_format *format, int rtp_code, const ch
 	ast_rwlock_unlock(&mime_types_lock);
 }
 
-static void add_static_payload(int map, struct ast_format *format, int rtp_code)
+static void add_static_payload(int payload, struct ast_format *format, int rtp_code)
 {
-	int x;
 	struct ast_rtp_payload_type *type;
 
 	/*
 	 * ARRAY_LEN's result is cast to an int so 'map' is not autocast to a size_t,
 	 * which if negative would cause an assertion.
 	 */
-	ast_assert(map < (int)ARRAY_LEN(static_RTP_PT));
+	ast_assert(payload < (int)ARRAY_LEN(static_RTP_PT));
 
+	if (ast_option_rtpusedynamic && payload < 0) {
+		/*
+		 * We're going to build dynamic payloads dynamically. An RTP code is
+		 * required otherwise one will be dynamically allocated per instance.
+		 */
+		return;
+	}
+
+	/*
+	 * Either the given payload is truly a static type, or Asterisk is
+	 * globally storing the dynamic payloads in the static_RTP_PT object.
+	 */
 	ast_rwlock_wrlock(&static_RTP_PT_lock);
-	if (map < 0) {
-		/* find next available dynamic payload slot */
-		for (x = AST_RTP_PT_FIRST_DYNAMIC; x < AST_RTP_MAX_PT; ++x) {
-			if (!static_RTP_PT[x]) {
-				map = x;
-				break;
-			}
-		}
 
-		/* http://www.iana.org/assignments/rtp-parameters
-		 * RFC 3551, Section 3: "[...] applications which need to define more
-		 * than 32 dynamic payload types MAY bind codes below 96, in which case
-		 * it is RECOMMENDED that unassigned payload type numbers be used
-		 * first". Updated by RFC 5761, Section 4: "[...] values in the range
-		 * 64-95 MUST NOT be used [to avoid conflicts with RTCP]". Summaries:
-		 * https://tools.ietf.org/html/draft-roach-mmusic-unified-plan#section-3.2.1.2
-		 * https://tools.ietf.org/html/draft-wu-avtcore-dynamic-pt-usage#section-3
-		 */
-		if (map < 0) {
-			for (x = MAX(ast_option_rtpptdynamic, 35); x <= AST_RTP_PT_LAST_REASSIGN; ++x) {
-				if (!static_RTP_PT[x]) {
-					map = x;
-					break;
-				}
-			}
-		}
-		/* Yet, reusing mappings below 35 is not supported in Asterisk because
-		 * when Compact Headers are activated, no rtpmap is send for those below
-		 * 35. If you want to use 35 and below
-		 * A) do not use Compact Headers,
-		 * B) remove that code in chan_sip/res_pjsip, or
-		 * C) add a flag that this RTP Payload Type got reassigned dynamically
-		 *    and requires a rtpmap even with Compact Headers enabled.
+	if (payload < 0) {
+		/*
+		 * This is a dynamic payload that will be stored globally,
+		 * so find the next available empty slot.
 		 */
-		if (map < 0) {
-			for (x = MAX(ast_option_rtpptdynamic, 20); x < 35; ++x) {
-				if (!static_RTP_PT[x]) {
-					map = x;
-					break;
-				}
-			}
-		}
-		if (map < 0) {
-			for (x = MAX(ast_option_rtpptdynamic, 0); x < 20; ++x) {
-				if (!static_RTP_PT[x]) {
-					map = x;
-					break;
-				}
-			}
-		}
-
-		if (map < 0) {
-			if (format) {
-				ast_log(LOG_WARNING, "No Dynamic RTP mapping available for format %s\n",
-					ast_format_get_name(format));
-			} else {
-				ast_log(LOG_WARNING, "No Dynamic RTP mapping available for RTP code %d\n",
-					rtp_code);
-			}
-			ast_rwlock_unlock(&static_RTP_PT_lock);
+		payload = find_unused_payload(NULL);
+		if (payload < 0) {
+			ast_log(LOG_WARNING, "No dynamic RTP payload type values available "
+				"for %s - %d!\n", format ? ast_format_get_name(format) : "", rtp_code);
 			return;
 		}
 	}
 
-	type = ast_rtp_engine_alloc_payload_type();
+	type = rtp_payload_type_alloc(format, payload, rtp_code, 1);
 	if (type) {
-		if (format) {
-			ao2_ref(format, +1);
-			type->format = format;
-			type->asterisk_format = 1;
-		} else {
-			type->rtp_code = rtp_code;
-		}
-		type->payload = map;
-		type->primary_mapping = 1;
-		ao2_cleanup(static_RTP_PT[map]);
-		static_RTP_PT[map] = type;
+		ao2_cleanup(static_RTP_PT[payload]);
+		static_RTP_PT[payload] = type;
 	}
 	ast_rwlock_unlock(&static_RTP_PT_lock);
 }
@@ -2797,23 +2841,34 @@ int ast_rtp_engine_init(void)
 	add_static_payload(26, ast_format_jpeg, 0);
 	add_static_payload(31, ast_format_h261, 0);
 	add_static_payload(34, ast_format_h263, 0);
+
+	/*
+	 * Dynamic payload types - Even when dynamically assigning them we'll fall
+	 * back to using the statically declared values as the default number.
+	 */
+	add_static_payload(96, ast_format_slin192, 0);
 	add_static_payload(97, ast_format_ilbc, 0);
 	add_static_payload(98, ast_format_h263p, 0);
 	add_static_payload(99, ast_format_h264, 0);
+	add_static_payload(100, ast_format_vp8, 0);
 	add_static_payload(101, NULL, AST_RTP_DTMF);
 	add_static_payload(102, ast_format_siren7, 0);
 	add_static_payload(103, ast_format_h263p, 0);
 	add_static_payload(104, ast_format_mp4, 0);
 	add_static_payload(105, ast_format_t140_red, 0);   /* Real time text chat (with redundancy encoding) */
 	add_static_payload(106, ast_format_t140, 0);     /* Real time text chat */
+	add_static_payload(107, ast_format_opus, 0);
+
 	add_static_payload(110, ast_format_speex, 0);
 	add_static_payload(111, ast_format_g726, 0);
 	add_static_payload(112, ast_format_g726_aal2, 0);
+
 	add_static_payload(115, ast_format_siren14, 0);
 	add_static_payload(116, ast_format_g719, 0);
 	add_static_payload(117, ast_format_speex16, 0);
 	add_static_payload(118, ast_format_slin16, 0); /* 16 Khz signed linear */
 	add_static_payload(119, ast_format_speex32, 0);
+
 	add_static_payload(121, NULL, AST_RTP_CISCO_DTMF);   /* Must be type 121 */
 	add_static_payload(122, ast_format_slin12, 0);
 	add_static_payload(123, ast_format_slin24, 0);
@@ -2822,10 +2877,6 @@ int ast_rtp_engine_init(void)
 	add_static_payload(126, ast_format_slin48, 0);
 	add_static_payload(127, ast_format_slin96, 0);
 	/* payload types above 127 are not valid */
-	add_static_payload(96, ast_format_slin192, 0);
-	/* Opus and VP8 */
-	add_static_payload(100, ast_format_vp8, 0);
-	add_static_payload(107, ast_format_opus, 0);
 
 	return 0;
 }