diff --git a/src/mod/applications/mod_av/autoload_configs/av.conf.xml b/src/mod/applications/mod_av/autoload_configs/av.conf.xml
new file mode 100644
index 0000000000..d9aaa0abcc
--- /dev/null
+++ b/src/mod/applications/mod_av/autoload_configs/av.conf.xml
@@ -0,0 +1,144 @@
+<configuration name="avcodec.conf" description="AVCodec Config">
+  <settings>
+    <!-- max bitrate the system support, truncate if over limit -->
+    <!-- <param name="max-bitrate" value="5mb"/> -->
+
+    <!-- <param name="rtp-slice-size" value="1200"/> -->
+
+    <!-- minimum time to generate a new key frame in ms /> -->
+    <!-- <param name="key-frame-min-freq" value="250"/> -->
+
+    <!-- integer of cpus, or 'auto', or 'cpu/<divisor>/<max> -->
+    <param name="dec-threads" value="cpu/2/4"/>
+    <param name="enc-threads" value="cpu/2/4"/>
+    <param name="h263-profile" value="H263"/>
+    <param name="h263+-profile" value="H263+"/>
+    <param name="h264-profile" value="H264"/>
+    <param name="h265-profile" value="H265"/>
+  </settings>
+
+  <profiles>
+    <profile name="H263">
+    </profile>
+
+    <profile name="H263+">
+    </profile>
+
+    <profile name="H264">
+      <!-- <param name="dec-threads" value="cpu/2/4"/> -->
+      <!-- <param name="enc-threads" value="1"/> -->
+
+      <!-- <param name="profile" value="2"/> -->
+      <!-- <param name="level" value="41"/> -->
+      <!-- <param name="timebase" value="1/90"/> -->
+
+<!--
+
+#define AV_CODEC_FLAG_UNALIGNED       (1 <<  0)
+#define AV_CODEC_FLAG_QSCALE          (1 <<  1)
+#define AV_CODEC_FLAG_4MV             (1 <<  2)
+#define AV_CODEC_FLAG_OUTPUT_CORRUPT  (1 <<  3)
+#define AV_CODEC_FLAG_QPEL            (1 <<  4)
+#define AV_CODEC_FLAG_PASS1           (1 <<  9)
+#define AV_CODEC_FLAG_PASS2           (1 << 10)
+#define AV_CODEC_FLAG_LOOP_FILTER     (1 << 11)
+#define AV_CODEC_FLAG_GRAY            (1 << 13)
+#define AV_CODEC_FLAG_PSNR            (1 << 15)
+#define AV_CODEC_FLAG_TRUNCATED       (1 << 16)
+#define AV_CODEC_FLAG_INTERLACED_DCT  (1 << 18)
+#define AV_CODEC_FLAG_LOW_DELAY       (1 << 19)
+#define AV_CODEC_FLAG_GLOBAL_HEADER   (1 << 22)
+#define AV_CODEC_FLAG_BITEXACT        (1 << 23)
+#define AV_CODEC_FLAG_AC_PRED         (1 << 24)
+#define AV_CODEC_FLAG_INTERLACED_ME   (1 << 29)
+#define AV_CODEC_FLAG_CLOSED_GOP      (1U << 31)
+
+-->
+
+      <param name="flags" value="LOOP_FILTER|PSNR"/>
+
+<!--
+#define FF_CMP_SAD          0
+#define FF_CMP_SSE          1
+#define FF_CMP_SATD         2
+#define FF_CMP_DCT          3
+#define FF_CMP_PSNR         4
+#define FF_CMP_BIT          5
+#define FF_CMP_RD           6
+#define FF_CMP_ZERO         7
+#define FF_CMP_VSAD         8
+#define FF_CMP_VSSE         9
+#define FF_CMP_NSSE         10
+#define FF_CMP_W53          11
+#define FF_CMP_W97          12
+#define FF_CMP_DCTMAX       13
+#define FF_CMP_DCT264       14
+#define FF_CMP_MEDIAN_SAD   15
+#define FF_CMP_CHROMA       256
+-->
+
+      <!-- <param name="me-cmp" value="1"/> -->
+      <!-- <param name="me-range" value="16"/> -->
+      <!-- <param name="max-b-frames" value="3"/> -->
+      <!-- <param name="refs" value="3"/> -->
+      <!-- <param name="gop-size" value="250"/> -->
+      <!-- <param name="keyint-min" value="25"/> -->
+      <!-- <param name="i-quant-factor" value="0.71"/> -->
+      <!-- <param name="b-quant-factor" value="0.76923078"/> -->
+      <!-- <param name="qcompress" value="0.6"/> -->
+      <!-- <param name="qmin" value="10"/> -->
+      <!-- <param name="qmax" value="51"/> -->
+      <!-- <param name="max-qdiff" value="4"/> -->
+
+<!--
+enum AVColorSpace {
+    AVCOL_SPC_RGB         = 0,  ///< order of coefficients is actually GBR, also IEC 61966-2-1 (sRGB)
+    AVCOL_SPC_BT709       = 1,  ///< also ITU-R BT1361 / IEC 61966-2-4 xvYCC709 / SMPTE RP177 Annex B
+    AVCOL_SPC_UNSPECIFIED = 2,
+    AVCOL_SPC_RESERVED    = 3,
+    AVCOL_SPC_FCC         = 4,  ///< FCC Title 47 Code of Federal Regulations 73.682 (a)(20)
+    AVCOL_SPC_BT470BG     = 5,  ///< also ITU-R BT601-6 625 / ITU-R BT1358 625 / ITU-R BT1700 625 PAL & SECAM / IEC 61966-2-4 xvYCC601
+    AVCOL_SPC_SMPTE170M   = 6,  ///< also ITU-R BT601-6 525 / ITU-R BT1358 525 / ITU-R BT1700 NTSC
+    AVCOL_SPC_SMPTE240M   = 7,  ///< functionally identical to above
+    AVCOL_SPC_YCGCO       = 8,  ///< Used by Dirac / VC-2 and H.264 FRext, see ITU-T SG16
+    AVCOL_SPC_YCOCG       = AVCOL_SPC_YCGCO,
+    AVCOL_SPC_BT2020_NCL  = 9,  ///< ITU-R BT2020 non-constant luminance system
+    AVCOL_SPC_BT2020_CL   = 10, ///< ITU-R BT2020 constant luminance system
+    AVCOL_SPC_SMPTE2085   = 11, ///< SMPTE 2085, Y'D'zD'x
+    AVCOL_SPC_CHROMA_DERIVED_NCL = 12, ///< Chromaticity-derived non-constant luminance system
+    AVCOL_SPC_CHROMA_DERIVED_CL = 13, ///< Chromaticity-derived constant luminance system
+    AVCOL_SPC_ICTCP       = 14, ///< ITU-R BT.2100-0, ICtCp
+    AVCOL_SPC_NB                ///< Not part of ABI
+};
+-->
+      <param name="colorspace" value="0"/>
+
+<!--
+enum AVColorRange {
+    AVCOL_RANGE_UNSPECIFIED = 0,
+    AVCOL_RANGE_MPEG        = 1, ///< the normal 219*2^(n-8) "MPEG" YUV ranges
+    AVCOL_RANGE_JPEG        = 2, ///< the normal     2^n-1   "JPEG" YUV ranges
+    AVCOL_RANGE_NB               ///< Not part of ABI
+};
+-->
+      <param name="color-range" value="2"/>
+
+      <!-- x264 private -->
+      <param name="x264-preset" value="veryfast"/>
+      <param name="x264-intra-refresh" value="1"/>
+      <param name="x264-tune" value="animation+zerolatency"/>
+      <!-- <param name="x264-sc-threshold" value="40"/> -->
+      <!-- <param name="x264-b-strategy" value="1"/> -->
+      <!-- <param name="x264-crf" value="18"/> -->
+
+    </profile>
+
+    <profile name="H265">
+    </profile>
+  </profiles>
+</configuration>
+
+<configuration name="avformat.conf" description="AVFormat Config">
+  <settings>
+  </settings>
+</configuration>
diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c
index d6bfca0167..593581825d 100644
--- a/src/mod/applications/mod_av/avcodec.c
+++ b/src/mod/applications/mod_av/avcodec.c
@@ -38,10 +38,12 @@
 #include <libavutil/opt.h>
 #include <libavutil/imgutils.h>
 
-#define SLICE_SIZE SWITCH_DEFAULT_VIDEO_SIZE
+int SLICE_SIZE = SWITCH_DEFAULT_VIDEO_SIZE;
+
 #define H264_NALU_BUFFER_SIZE 65536
-#define MAX_NALUS 128
+#define MAX_NALUS 256
 #define H263_MODE_B // else Mode A only
+#define KEY_FRAME_MIN_FREQ 250000
 
 SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load);
 
@@ -194,6 +196,55 @@ typedef struct h264_codec_context_s {
 
 static uint8_t ff_input_buffer_padding[FF_INPUT_BUFFER_PADDING_SIZE] = { 0 };
 
+#define MAX_CODECS 4
+
+typedef struct avcodec_profile_s {
+	char name[20];
+	int decoder_thread_count;
+	AVCodecContext ctx;
+	struct {
+		char preset[20];
+		char tune[64];
+		int intra_refresh;
+		int sc_threshold;
+		int b_strategy;
+		int crf;
+	} x264;
+} avcodec_profile_t;
+
+struct avcodec_globals {
+	int debug;
+	uint32_t max_bitrate;
+	uint32_t rtp_slice_size;
+	uint32_t key_frame_min_freq;
+
+	avcodec_profile_t profiles[MAX_CODECS];
+};
+
+struct avcodec_globals avcodec_globals = { 0 };
+
+char *CODEC_MAPS[] = {
+	"H263",
+	"H263+",
+	"H264",
+	"H265",
+	NULL
+};
+
+static int get_codec_index(const char *cstr)
+{
+	int i;
+
+	for (i = 0; ; i++) {
+		if (!strcasecmp(cstr, CODEC_MAPS[i])) {
+			return i;
+		}
+	}
+
+	abort();
+	return -1;
+}
+
 static switch_status_t buffer_h264_nalu(h264_codec_context_t *context, switch_frame_t *frame)
 {
 	uint8_t nalu_type = 0;
@@ -827,9 +878,8 @@ static switch_status_t consume_nalu(h264_codec_context_t *context, switch_frame_
 
 static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t width, uint32_t height)
 {
-	int sane = 0;
-	int threads = switch_core_cpu_count();
 	int fps = 15;
+	avcodec_profile_t *profile = NULL;
 	
 #ifdef NVENC_SUPPORT
 	if (!context->encoder) {
@@ -860,6 +910,18 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt
 		return SWITCH_STATUS_FALSE;
 	}
 
+	if (context->av_codec_id == AV_CODEC_ID_H263) {
+		profile = &avcodec_globals.profiles[get_codec_index("H263")];
+	} else if (context->av_codec_id == AV_CODEC_ID_H263P) {
+		profile = &avcodec_globals.profiles[get_codec_index("H263+")];
+	} else if (context->av_codec_id == AV_CODEC_ID_H264) {
+		profile = &avcodec_globals.profiles[get_codec_index("H264")];
+	} else if (context->av_codec_id == AV_CODEC_ID_H265) {
+		profile = &avcodec_globals.profiles[get_codec_index("H265")];
+	}
+
+	if (!profile) return SWITCH_STATUS_FALSE;
+
 	if (context->encoder_ctx) {
 		if (avcodec_is_open(context->encoder_ctx)) {
 			avcodec_close(context->encoder_ctx);
@@ -896,15 +958,11 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt
 		context->bandwidth = switch_calc_bitrate(context->codec_settings.video.width, context->codec_settings.video.height, 1, fps);
 	}
 
-	sane = switch_calc_bitrate(1920, 1080, 3, 60);
-
-	if (context->bandwidth > sane) {
-		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BITRATE TRUNCATED TO %d\n", sane);
-		context->bandwidth = sane;
+	if (context->bandwidth > avcodec_globals.max_bitrate) {
+		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "BITRATE TRUNCATED TO %d\n", avcodec_globals.max_bitrate);
+		context->bandwidth = avcodec_globals.max_bitrate;
 	}
 
-	if (threads > 4) threads = 4;
-
 	context->bandwidth *= 3;
 
 	fps = context->codec_settings.video.fps;
@@ -921,11 +979,10 @@ static switch_status_t open_encoder(h264_codec_context_t *context, uint32_t widt
 	
 	context->encoder_ctx->width = context->codec_settings.video.width;
 	context->encoder_ctx->height = context->codec_settings.video.height;
-	/* frames per second */
 	context->encoder_ctx->time_base = (AVRational){1, 90};
-	context->encoder_ctx->max_b_frames = 0;
+	context->encoder_ctx->max_b_frames = profile->ctx.max_b_frames;
 	context->encoder_ctx->pix_fmt = AV_PIX_FMT_YUV420P;
-	context->encoder_ctx->thread_count = threads;
+	context->encoder_ctx->thread_count = profile->ctx.thread_count;
 
 	if (context->av_codec_id == AV_CODEC_ID_H263 || context->av_codec_id == AV_CODEC_ID_H263P) {
 #ifndef H263_MODE_B
@@ -946,44 +1003,38 @@ FF_ENABLE_DEPRECATION_WARNINGS
 		context->encoder_ctx->opaque = context;
 		av_opt_set_int(context->encoder_ctx->priv_data, "mb_info", SLICE_SIZE - 8, 0);
 	} else if (context->av_codec_id == AV_CODEC_ID_H264) {
-		context->encoder_ctx->profile = FF_PROFILE_H264_BASELINE;
-		context->encoder_ctx->level = 31;
+		context->encoder_ctx->profile = profile->ctx.profile;
+		context->encoder_ctx->level = profile->ctx.level;
 
 		if (context->hw_encoder) {
 			av_opt_set(context->encoder_ctx->priv_data, "preset", "llhp", 0);
 			av_opt_set_int(context->encoder_ctx->priv_data, "2pass", 1, 0);
 		} else {
-			av_opt_set_int(context->encoder_ctx->priv_data, "intra-refresh", 1, 0);
-			av_opt_set(context->encoder_ctx->priv_data, "preset", "veryfast", 0);
-			av_opt_set(context->encoder_ctx->priv_data, "tune", "animation+zerolatency", 0);
-			av_opt_set(context->encoder_ctx->priv_data, "profile", "baseline", 0);
+			av_opt_set_int(context->encoder_ctx->priv_data, "intra-refresh", profile->x264.intra_refresh, 0);
+			av_opt_set(context->encoder_ctx->priv_data, "preset", profile->x264.preset, 0);
+			av_opt_set(context->encoder_ctx->priv_data, "tune", profile->x264.tune, 0);
 			av_opt_set_int(context->encoder_ctx->priv_data, "slice-max-size", SLICE_SIZE, 0);
 
-			
-			context->encoder_ctx->colorspace = AVCOL_SPC_RGB;
-			context->encoder_ctx->color_range = AVCOL_RANGE_JPEG;
+			context->encoder_ctx->colorspace = profile->ctx.colorspace;
+			context->encoder_ctx->color_range = profile->ctx.color_range;
 
-			/*
-			av_opt_set_int(context->encoder_ctx->priv_data, "sc_threshold", 40, 0);
-			av_opt_set_int(context->encoder_ctx->priv_data, "b_strategy", 1, 0);
-			av_opt_set_int(context->encoder_ctx->priv_data, "crf",  18, 0);
+			if (profile->x264.sc_threshold > 0) av_opt_set_int(context->encoder_ctx->priv_data, "sc_threshold", profile->x264.sc_threshold, 0);
+			if (profile->x264.b_strategy > 0)av_opt_set_int(context->encoder_ctx->priv_data, "b_strategy", profile->x264.b_strategy, 0);
+			if (profile->x264.crf > 0)av_opt_set_int(context->encoder_ctx->priv_data, "crf",  profile->x264.crf, 0);
 
-			// libx264-medium.ffpreset preset
-
-			context->encoder_ctx->flags|=CODEC_FLAG_LOOP_FILTER;   // flags=+loop
-			context->encoder_ctx->me_cmp|= 1;  // cmp=+chroma, where CHROMA = 1
-			context->encoder_ctx->me_range = 21;   // me_range=16
-			context->encoder_ctx->max_b_frames = 3;    // bf=3
-			//context->encoder_ctx->refs = 3;    // refs=3
-			context->encoder_ctx->gop_size = 250;  // g=250
-			context->encoder_ctx->keyint_min = 25; // keyint_min=25
-			context->encoder_ctx->i_quant_factor = 0.71; // i_qfactor=0.71
-			context->encoder_ctx->b_quant_factor = 0.76923078; // Qscale difference between P-frames and B-frames.
-			context->encoder_ctx->qcompress = 0;//0.6; // qcomp=0.6
-			context->encoder_ctx->qmin = 10;   // qmin=10
-			context->encoder_ctx->qmax = 51;   // qmax=51
-			context->encoder_ctx->max_qdiff = 4;   // qdiff=4
-			*/
+			context->encoder_ctx->flags |= profile->ctx.flags; // CODEC_FLAG_LOOP_FILTER;   // flags=+loop
+			if (profile->ctx.me_cmp >= 0) context->encoder_ctx->me_cmp = profile->ctx.me_cmp;  // cmp=+chroma, where CHROMA = 1
+			if (profile->ctx.me_range >= 0) context->encoder_ctx->me_range = profile->ctx.me_range;
+			if (profile->ctx.max_b_frames >= 0) context->encoder_ctx->max_b_frames = profile->ctx.max_b_frames;
+			if (profile->ctx.refs >= 0) context->encoder_ctx->refs = profile->ctx.refs;
+			if (profile->ctx.gop_size >= 0) context->encoder_ctx->gop_size = profile->ctx.gop_size;
+			if (profile->ctx.keyint_min >= 0) context->encoder_ctx->keyint_min = profile->ctx.keyint_min;
+			if (profile->ctx.i_quant_factor >= 0) context->encoder_ctx->i_quant_factor = profile->ctx.i_quant_factor;
+			if (profile->ctx.b_quant_factor >= 0) context->encoder_ctx->b_quant_factor = profile->ctx.b_quant_factor;
+			if (profile->ctx.qcompress >= 0) context->encoder_ctx->qcompress = profile->ctx.qcompress;
+			if (profile->ctx.qmin >= 0) context->encoder_ctx->qmin = profile->ctx.qmin;
+			if (profile->ctx.qmax >= 0) context->encoder_ctx->qmax = profile->ctx.qmax;
+			if (profile->ctx.max_qdiff >= 0) context->encoder_ctx->max_qdiff = profile->ctx.max_qdiff;
 		}
 	}
 
@@ -999,7 +1050,7 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
 {
 	int encoding, decoding;
 	h264_codec_context_t *context = NULL;
-	int threads = switch_core_cpu_count();
+	avcodec_profile_t *profile = NULL;
 
 	encoding = (flags & SWITCH_CODEC_FLAG_ENCODE);
 	decoding = (flags & SWITCH_CODEC_FLAG_DECODE);
@@ -1022,12 +1073,17 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
 
 	if (!strcmp(codec->implementation->iananame, "H263")) {
 		context->av_codec_id = AV_CODEC_ID_H263;
+		profile = &avcodec_globals.profiles[get_codec_index("H263")];
 	} else if (!strcmp(codec->implementation->iananame, "H263-1998")) {
 		context->av_codec_id = AV_CODEC_ID_H263P;
+		profile = &avcodec_globals.profiles[get_codec_index("H263+")];
 	} else {
 		context->av_codec_id = AV_CODEC_ID_H264;
+		profile = &avcodec_globals.profiles[get_codec_index("H264")];
 	}
 
+	switch_assert(profile);
+
 	if (decoding) {
 		context->decoder = avcodec_find_decoder(context->av_codec_id);
 
@@ -1042,11 +1098,9 @@ static switch_status_t switch_h264_init(switch_codec_t *codec, switch_codec_flag
 		}
 
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "codec: id=%d %s\n", context->decoder->id, context->decoder->long_name);
-
-		if (threads > 4) threads = 4;
 		
 		context->decoder_ctx = avcodec_alloc_context3(context->decoder);
-		//context->decoder_ctx->thread_count = threads;
+		context->decoder_ctx->thread_count = profile->decoder_thread_count;
 		if (avcodec_open2(context->decoder_ctx, context->decoder, NULL) < 0) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error openning codec\n");
 			goto error;
@@ -1247,6 +1301,10 @@ GCC_DIAG_ON(deprecated-declarations)
 				while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
 				context->nalus[i].start = p;
 				context->nalus[i].eat = p;
+
+				if (mod_av_globals.debug && (*p & 0x1f) == 7) {
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "KEY FRAME GENERATED\n");
+				}
 			} else {
 				context->nalus[i].len = p - context->nalus[i].start;
 				while (!(*p++)) ; /* eat the sync bytes, what ever 0 0 1 or 0 0 0 1 */
@@ -1558,10 +1616,302 @@ void show_codecs(switch_stream_handle_t *stream)
 	av_free(codecs);
 }
 
+#define UINTVAL(v) (v > 0 ? v : 0);
+
+static void load_config()
+{
+	switch_xml_t cfg = NULL, xml = NULL;
+	int i;
+
+	switch_set_string(avcodec_globals.profiles[get_codec_index("H263")].name, "H263");
+	switch_set_string(avcodec_globals.profiles[get_codec_index("H263+")].name, "H263+");
+	switch_set_string(avcodec_globals.profiles[get_codec_index("H264")].name, "H264");
+	switch_set_string(avcodec_globals.profiles[get_codec_index("H265")].name, "H265");
+
+	for (i = 0; i < MAX_CODECS; i++) {
+		avcodec_profile_t *profile = &avcodec_globals.profiles[i];
+
+		profile->ctx.colorspace = AVCOL_SPC_RGB;
+		profile->ctx.color_range = AVCOL_RANGE_JPEG;
+		profile->ctx.flags = 0;
+		profile->ctx.me_cmp = -1;
+		profile->ctx.me_range = -1;
+		profile->ctx.max_b_frames = -1;
+		profile->ctx.refs = -1;
+		profile->ctx.gop_size = -1;
+		profile->ctx.keyint_min = -1;
+		profile->ctx.i_quant_factor = -1;
+		profile->ctx.b_quant_factor = -1;
+		profile->ctx.qcompress = -1;
+		profile->ctx.qmin = -1;
+		profile->ctx.qmax = -1;
+		profile->ctx.max_qdiff = -1;
+
+		profile->x264.sc_threshold = 0;
+		profile->x264.b_strategy = 0;
+		profile->x264.crf = 0;
+
+		if (!strcasecmp(CODEC_MAPS[i], "H264")) {
+			profile->ctx.profile = FF_PROFILE_H264_BASELINE;
+			profile->ctx.level = 41;
+		}
+	}
+
+	avcodec_globals.max_bitrate = 0;
+
+	xml = switch_xml_open_cfg("avcodec.conf", &cfg, NULL);
+
+	if (xml) {
+		switch_xml_t settings = switch_xml_child(cfg, "settings");
+		switch_xml_t profiles = switch_xml_child(cfg, "profiles");
+
+		if (settings) {
+			switch_xml_t param;
+
+			for (param = switch_xml_child(settings, "param"); param; param = param->next) {
+				const char *name = switch_xml_attr(param, "name");
+				const char *value = switch_xml_attr(param, "value");
+
+				if (zstr(name) || zstr(value)) continue;
+
+				if (!strcmp(name, "max-bitrate")) {
+					avcodec_globals.max_bitrate = switch_parse_bandwidth_string(value);
+				} else if (!strcmp(name, "rtp-slice-size")) {
+					int val = atoi(value);
+					avcodec_globals.rtp_slice_size = UINTVAL(val);
+				} else if (!strcmp(name, "key-frame-min-freq")) {
+					int val = atoi(value);
+					avcodec_globals.key_frame_min_freq = UINTVAL(val);
+					avcodec_globals.key_frame_min_freq *= 1000;
+				} else if (!strcmp(name, "dec-threads")) {
+					int i;
+					uint threads = switch_parse_cpu_string(value);
+
+					for (i = 0; i < MAX_CODECS; i++) {
+						avcodec_globals.profiles[i].decoder_thread_count = threads;
+					}
+				} else if (!strcmp(name, "enc-threads")) {
+					int i;
+					uint threads = switch_parse_cpu_string(value);
+
+					for (i = 0; i < MAX_CODECS; i++) {
+						avcodec_globals.profiles[i].ctx.thread_count = threads;
+					}
+				} else if (!strcasecmp(name, "h263-profile")) {
+					switch_set_string(avcodec_globals.profiles[get_codec_index("H263")].name, value);
+				} else if (!strcasecmp(name, "h263+-profile")) {
+					switch_set_string(avcodec_globals.profiles[get_codec_index("H263+")].name, value);
+				} else if (!strcasecmp(name, "h264-profile")) {
+					switch_set_string(avcodec_globals.profiles[get_codec_index("H264")].name, value);
+				} else if (!strcasecmp(name, "h265-profile")) {
+					switch_set_string(avcodec_globals.profiles[get_codec_index("H265")].name, value);
+				}
+			}
+		}
+
+		if (profiles) {
+			switch_xml_t profile = switch_xml_child(profiles, "profile");
+
+			for (; profile; profile = profile->next) {
+				switch_xml_t param = NULL;
+				const char *profile_name = switch_xml_attr(profile, "name");
+				avcodec_profile_t *aprofile = NULL;
+				AVCodecContext *ctx = NULL;
+				int i;
+
+				if (zstr(profile_name)) continue;
+
+				for (i = 0; i < MAX_CODECS; i++) {
+					if (!strcmp(profile_name, avcodec_globals.profiles[i].name)) {
+						aprofile = &avcodec_globals.profiles[i];
+						ctx = &aprofile->ctx;
+						break;
+					}
+				}
+
+				if (!ctx) continue;
+
+				for (param = switch_xml_child(profile, "param"); param; param = param->next) {
+					const char *name = switch_xml_attr(param, "name");
+					const char *value = switch_xml_attr(param, "value");
+					int val;
+
+					if (zstr(name) || zstr(value)) continue;
+
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s: %s = %s\n", profile_name, name, value);
+
+					val = atoi(value);
+
+					if (!strcmp(name, "dec-threads")) {
+						aprofile->decoder_thread_count = switch_parse_cpu_string(value);
+					} else if (!strcmp(name, "enc-threads")) {
+						ctx->thread_count = switch_parse_cpu_string(value);
+					} else if (!strcmp(name, "profile")) {
+						ctx->profile = UINTVAL(val);
+
+						if (ctx->profile == 0 && !strcasecmp(CODEC_MAPS[i], "H264")) {
+							if (!strcasecmp(value, "baseline")) {
+								ctx->profile = FF_PROFILE_H264_BASELINE;
+							} else if (!strcasecmp(value, "main")) {
+								ctx->profile = FF_PROFILE_H264_MAIN;
+							} else if (!strcasecmp(value, "high")) {
+								ctx->profile = FF_PROFILE_H264_HIGH;
+							}
+						}
+					} else if (!strcmp(name, "level")) {
+						ctx->level = UINTVAL(val);
+					} else if (!strcmp(name, "timebase")) {
+						int num = 0;
+						int den = 0;
+						char *slash = strchr(value, '/');
+
+						num = UINTVAL(val);
+
+						if (slash) {
+							slash++;
+							den = atoi(slash);
+
+							if (den < 0) den = 0;
+						}
+
+						if (num && den) {
+							ctx->time_base.num = num;
+							ctx->time_base.den = den;
+						}
+					} else if (!strcmp(name, "preset")) {
+						switch_set_string(aprofile->x264.preset, value);
+					} else if (!strcmp(name, "flags")) {
+						char *s = strdup(value);
+						int flags = 0;
+
+						if (s) {
+							int argc;
+							char *argv[20];
+							int i;
+
+							argc = switch_separate_string(s, '|', argv, (sizeof(argv) / sizeof(argv[0])));
+
+							for (i = 0; i < argc; i++) {
+								if (!strcasecmp(argv[i], "UNALIGNED")) {
+									flags |= AV_CODEC_FLAG_UNALIGNED;
+								} else if (!strcasecmp(argv[i], "QSCALE")) {
+									flags |= AV_CODEC_FLAG_QSCALE;
+								} else if (!strcasecmp(argv[i], "QSCALE")) {
+									flags |= AV_CODEC_FLAG_QSCALE;
+								} else if (!strcasecmp(argv[i], "4MV")) {
+									flags |= AV_CODEC_FLAG_4MV;
+								} else if (!strcasecmp(argv[i], "CORRUPT")) {
+									flags |= AV_CODEC_FLAG_OUTPUT_CORRUPT;
+								} else if (!strcasecmp(argv[i], "QPEL")) {
+									flags |= AV_CODEC_FLAG_QPEL;
+								} else if (!strcasecmp(argv[i], "PASS1")) {
+									flags |= AV_CODEC_FLAG_PASS1;
+								} else if (!strcasecmp(argv[i], "PASS2")) {
+									flags |= AV_CODEC_FLAG_PASS2;
+								} else if (!strcasecmp(argv[i], "FILTER")) {
+									flags |= AV_CODEC_FLAG_LOOP_FILTER;
+								} else if (!strcasecmp(argv[i], "GRAY")) {
+									flags |= AV_CODEC_FLAG_GRAY;
+								} else if (!strcasecmp(argv[i], "PSNR")) {
+									flags |= AV_CODEC_FLAG_PSNR;
+								} else if (!strcasecmp(argv[i], "TRUNCATED")) {
+									flags |= AV_CODEC_FLAG_TRUNCATED;
+								} else if (!strcasecmp(argv[i], "INTERLACED_DCT")) {
+									flags |= AV_CODEC_FLAG_INTERLACED_DCT;
+								} else if (!strcasecmp(argv[i], "LOW_DELAY")) {
+									flags |= AV_CODEC_FLAG_LOW_DELAY;
+								} else if (!strcasecmp(argv[i], "HEADER")) {
+									flags |= AV_CODEC_FLAG_GLOBAL_HEADER;
+								} else if (!strcasecmp(argv[i], "BITEXACT")) {
+									flags |= AV_CODEC_FLAG_BITEXACT;
+								} else if (!strcasecmp(argv[i], "AC_PRED")) {
+									flags |= AV_CODEC_FLAG_AC_PRED;
+								} else if (!strcasecmp(argv[i], "INTERLACED_ME")) {
+									flags |= AV_CODEC_FLAG_INTERLACED_ME;
+								} else if (!strcasecmp(argv[i], "CLOSED_GOP")) {
+									flags |= AV_CODEC_FLAG_CLOSED_GOP;
+								}
+							}
+
+							free(s);
+							ctx->flags = flags;
+						}
+					} else if (!strcmp(name, "me-cmp")) {
+						ctx->me_cmp = UINTVAL(val);
+					} else if (!strcmp(name, "me-range")) {
+						ctx->me_range = UINTVAL(val);
+					} else if (!strcmp(name, "max-b-frames")) {
+						ctx->max_b_frames = UINTVAL(val);
+					} else if (!strcmp(name, "refs")) {
+						ctx->refs = UINTVAL(val);
+					} else if (!strcmp(name, "gop-size")) {
+						ctx->gop_size = UINTVAL(val);
+					} else if (!strcmp(name, "keyint-min")) {
+						ctx->keyint_min = UINTVAL(val);
+					} else if (!strcmp(name, "i-quant-factor")) {
+						ctx->i_quant_factor = UINTVAL(val);
+					} else if (!strcmp(name, "b-quant-factor")) {
+						ctx->b_quant_factor = UINTVAL(val);
+					} else if (!strcmp(name, "qcompress")) {
+						ctx->qcompress = UINTVAL(val);
+					} else if (!strcmp(name, "qmin")) {
+						ctx->qmin = UINTVAL(val);
+					} else if (!strcmp(name, "qmax")) {
+						ctx->qmax = UINTVAL(val);
+					} else if (!strcmp(name, "max-qdiff")) {
+						ctx->max_qdiff = UINTVAL(val);
+					} else if (!strcmp(name, "colorspace")) {
+						ctx->colorspace = UINTVAL(val);
+
+						if (ctx->colorspace > AVCOL_SPC_NB) {
+							ctx->colorspace = AVCOL_SPC_RGB;
+						}
+					} else if (!strcmp(name, "color-range")) {
+						ctx->color_range = UINTVAL(val);
+
+						if (ctx->color_range >  AVCOL_RANGE_NB) {
+							ctx->color_range = 0;
+						}
+					} else if (!strcmp(name, "x264-preset")) {
+						switch_set_string(aprofile->x264.preset, value);
+					} else if (!strcmp(name, "x264-tune")) {
+						switch_set_string(aprofile->x264.tune, value);
+					} else if (!strcmp(name, "x264-sc-threshold")) {
+						aprofile->x264.sc_threshold = UINTVAL(val);
+					} else if (!strcmp(name, "x264-b-strategy")) {
+						aprofile->x264.b_strategy = UINTVAL(val);
+					} else if (!strcmp(name, "x264-crf")) {
+						aprofile->x264.crf = UINTVAL(val);
+					}
+				} // for param
+			} // for profile
+		} // profiles
+
+		switch_xml_free(xml);
+	} // xml
+
+	if (avcodec_globals.max_bitrate <= 0) {
+		avcodec_globals.max_bitrate = switch_calc_bitrate(1920, 1080, 5, 60);
+	}
+
+	if (avcodec_globals.rtp_slice_size < 500 || avcodec_globals.rtp_slice_size > 1500) {
+		avcodec_globals.rtp_slice_size = SWITCH_DEFAULT_VIDEO_SIZE;
+	}
+
+	SLICE_SIZE = avcodec_globals.rtp_slice_size;
+
+	if (avcodec_globals.key_frame_min_freq < 10000 || avcodec_globals.key_frame_min_freq > 3 * 1000000) {
+		avcodec_globals.key_frame_min_freq = KEY_FRAME_MIN_FREQ;
+	}
+}
+
 SWITCH_MODULE_LOAD_FUNCTION(mod_avcodec_load)
 {
 	switch_codec_interface_t *codec_interface;
 
+	memset(&avcodec_globals, 0, sizeof(struct avcodec_globals));
+	load_config();
+
 	SWITCH_ADD_CODEC(codec_interface, "H264 Video");
 	switch_core_codec_add_video_implementation(pool, codec_interface, 99, "H264", NULL,
 											   switch_h264_init, switch_h264_encode, switch_h264_decode, switch_h264_control, switch_h264_destroy);