diff --git a/conf/vanilla/autoload_configs/conference.conf.xml b/conf/vanilla/autoload_configs/conference.conf.xml
index a51d568337..30664e286f 100644
--- a/conf/vanilla/autoload_configs/conference.conf.xml
+++ b/conf/vanilla/autoload_configs/conference.conf.xml
@@ -175,9 +175,12 @@
       <param name="caller-id-number" value="$${outbound_caller_id}"/>
       <param name="comfort-noise" value="true"/>
 
+      <!--<param name="conference-flags" value="video-floor-only|rfc-4579|livearray-sync|auto-3d-position|transcode-video|minimize-video-encoding"/> -->
+
       <!-- <param name="video-layout-name" value="3x3"/> -->
       <!-- <param name="video-canvas-size" value="1280x720"/> -->
       <!-- <param name="video-canvas-bgcolor" value="#0000FF"/> -->
+      <!-- <param name="video-codec-bandwidth" value="2mb"/> -->
 
       <!--<param name="tts-engine" value="flite"/>-->
       <!--<param name="tts-voice" value="kal16"/>-->
diff --git a/conf/vanilla/autoload_configs/conference_layouts.conf.xml b/conf/vanilla/autoload_configs/conference_layouts.conf.xml
index 0c97ac1e01..26f149deb2 100644
--- a/conf/vanilla/autoload_configs/conference_layouts.conf.xml
+++ b/conf/vanilla/autoload_configs/conference_layouts.conf.xml
@@ -105,7 +105,7 @@
 	<image x="300" y="300" scale="60"/>
       </layout>
       <layout name="1up_top_left+5">
-	<image x="0" y="0" scale="240" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="240" floor="true"/>
 	<image x="240" y="0" scale="120"/>
 	<image x="240" y="120" scale="120"/>
 	<image x="0" y="240" scale="120"/>
@@ -113,7 +113,7 @@
 	<image x="240" y="240" scale="120"/>
       </layout>
       <layout name="1up_top_left+7">
-	<image x="0" y="0" scale="270" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="270" floor="true"/>
 	<image x="270" y="0" scale="90"/>
 	<image x="270" y="90" scale="90"/>
 	<image x="270" y="180" scale="90"/>
@@ -123,7 +123,7 @@
 	<image x="270" y="270" scale="90"/>
       </layout>
       <layout name="1up_top_left+9">
-	<image x="0" y="0" scale="288" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="288" floor="true"/>
 	<image x="288" y="0" scale="72"/>
 	<image x="288" y="72" scale="72"/>
 	<image x="288" y="144" scale="72"/>
@@ -135,7 +135,7 @@
 	<image x="288" y="288" scale="72"/>
       </layout>
       <layout name="2up_top+8">
-	<image x="0" y="0" scale="180" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="180" floor="true"/>
 	<image x="180" y="0" scale="180" reservation_id="secondary"/>
 	<image x="0" y="180" scale="90"/>
 	<image x="90" y="180" scale="90"/>
@@ -147,7 +147,7 @@
 	<image x="270" y="270" scale="90"/>
       </layout>
       <layout name="2up_middle+8">
-	<image x="0" y="90" scale="180" floor="true" reservation_id="primary"/>
+	<image x="0" y="90" scale="180" floor="true"/>
 	<image x="180" y="90" scale="180" reservation_id="secondary"/>
 	<image x="0" y="0" scale="90"/>
 	<image x="90" y="0" scale="90"/>
@@ -159,7 +159,7 @@
 	<image x="270" y="270" scale="90"/>
       </layout>
       <layout name="2up_bottom+8">
-	<image x="0" y="180" scale="180" floor="true" reservation_id="primary"/>
+	<image x="0" y="180" scale="180" floor="true"/>
 	<image x="180" y="180" scale="180" reservation_id="secondary"/>
 	<image x="0" y="0" scale="90"/>
 	<image x="90" y="0" scale="90"/>
@@ -171,7 +171,7 @@
 	<image x="270" y="90" scale="90"/>
       </layout>
       <layout name="3up+4">
-	<image x="0" y="0" scale="180" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="180" floor="true"/>
 	<image x="180" y="0" scale="180" reservation_id="secondary"/>
 	<image x="0" y="180" scale="180" reservation_id="third"/>
 	<image x="180" y="180" scale="90"/>
@@ -180,7 +180,7 @@
 	<image x="270" y="270" scale="90"/>
       </layout>
       <layout name="3up+9">
-	<image x="0" y="0" scale="180" floor="true" reservation_id="primary"/>
+	<image x="0" y="0" scale="180" floor="true"/>
 	<image x="180" y="0" scale="180" reservation_id="secondary"/>
 	<image x="0" y="180" scale="180" reservation_id="third"/>
 	<image x="180" y="180" scale="60"/>
diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h
index e922ff262a..4604e620b8 100644
--- a/src/include/switch_utils.h
+++ b/src/include/switch_utils.h
@@ -976,6 +976,27 @@ SWITCH_DECLARE(char *) switch_util_quote_shell_arg_pool(const char *string, swit
 
 #define SWITCH_READ_ACCEPTABLE(status) (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK || status == SWITCH_STATUS_INUSE)
 
+static inline uint32_t switch_parse_bandwidth_string(const char *bwv)
+{
+	uint32_t bw = 0;
+
+	if (!bwv) return 0;
+	
+	if (bwv && (bw = (uint32_t) atol(bwv))) {
+		if (bw < 0) return 0;
+
+		if (switch_stristr("KB", bwv)) {
+			bw *= 8;
+		} else if (switch_stristr("mb", bwv)) {
+			bw *= 1024;
+		} else if (switch_stristr("MB", bwv)) {
+			bw *= 8192;
+		}
+	}
+
+	return bw;
+}
+
 static inline int switch_needs_url_encode(const char *s)
 {
 	const char hex[] = "0123456789ABCDEF";
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index 80ddd0886c..42e9a446a6 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -231,8 +231,9 @@ typedef enum {
 	CFLAG_LIVEARRAY_SYNC = (1 << 21),
 	CFLAG_CONF_RESTART_AUTO_RECORD = (1 << 22),
 	CFLAG_POSITIONAL = (1 << 23),
-	CFLAG_DECODE_VIDEO = (1 << 24),
-	CFLAG_VIDEO_MUXING = (1 << 25)
+	CFLAG_TRANSCODE_VIDEO = (1 << 24),
+	CFLAG_VIDEO_MUXING = (1 << 25),
+	CFLAG_MINIMIZE_VIDEO_ENCODING = (1 << 26)
 } conf_flag_t;
 
 typedef enum {
@@ -342,6 +343,7 @@ typedef struct mcu_layer_geometry_s {
 	int scale;
 	int floor;
 	char *res_id;
+	char *audio_position;
 } mcu_layer_geometry_t;
 
 typedef struct mcu_layer_def_s {
@@ -352,6 +354,7 @@ typedef struct mcu_layer_def_s {
 typedef struct mcu_layer_s {
 	mcu_layer_geometry_t geometry;
 	int member_id;
+	int idx;
 	switch_image_t *img;
 	switch_image_t *cur_img;
 } mcu_layer_t;
@@ -370,6 +373,7 @@ typedef struct mcu_canvas_s {
 	mcu_layer_t layers[MCU_MAX_LAYERS];
 	int total_layers;
 	int layers_used;
+	int layout_floor_id;
 	bgcolor_yuv_t bgcolor;
 	switch_mutex_t *mutex;
 	switch_mutex_t *cond_mutex;
@@ -423,6 +427,7 @@ typedef struct conference_obj {
 	char *outcall_templ;
 	char *video_layout_name;
 	char *video_canvas_bgcolor;
+	uint32_t video_codec_bandwidth;
 	uint32_t canvas_width;
 	uint32_t canvas_height;
 	uint32_t terminate_on_silence;
@@ -674,7 +679,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem
 static switch_status_t conf_api_sub_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data);
 static switch_status_t conf_api_sub_vid_floor(conference_member_t *member, switch_stream_handle_t *stream, void *data);
 static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference, switch_stream_handle_t *stream, void *data);
-
+static switch_status_t conf_api_sub_position(conference_member_t *member, switch_stream_handle_t *stream, void *data);
 
 #define lock_member(_member) switch_mutex_lock(_member->write_mutex); switch_mutex_lock(_member->read_mutex)
 #define unlock_member(_member) switch_mutex_unlock(_member->read_mutex); switch_mutex_unlock(_member->write_mutex)
@@ -684,6 +689,7 @@ static switch_status_t conf_api_sub_clear_vid_floor(conference_obj_t *conference
 
 typedef struct layout_node_s {
 	char *name;
+	char *audio_position;
 	mcu_layer_geometry_t images[MCU_MAX_LAYERS];
 	struct layout_node_s *next;
 	int layers;
@@ -718,14 +724,13 @@ static void conference_parse_layouts(conference_obj_t *conference)
 	if ((x_layout_settings = switch_xml_child(cfg, "layout-settings"))) {
 		if ((x_layouts = switch_xml_child(x_layout_settings, "layouts"))) {
 			for (x_layout = switch_xml_child(x_layouts, "layout"); x_layout; x_layout = x_layout->next) {
-				layout_node_t *lnode;
-				int x = -1, y = -1, scale = -1, floor = 0;
-				const char *val, *res_id = NULL, *name = NULL;
+				layout_node_t *lnode;				
+				const char *val = NULL, *name = NULL;
 
 				if ((val = switch_xml_attr(x_layout, "name"))) {
 					name = val;
 				}
-				
+
 				if (!name) {
 					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid layout\n");
 					continue;
@@ -735,7 +740,9 @@ static void conference_parse_layouts(conference_obj_t *conference)
 				lnode->name = switch_core_strdup(conference->pool, name);
 
 				for (x_image = switch_xml_child(x_layout, "image"); x_image; x_image = x_image->next) {
-				
+					const char *res_id = NULL, *audio_position = NULL;
+					int x = -1, y = -1, scale = -1, floor = 0;
+
 					if ((val = switch_xml_attr(x_image, "x"))) {
 						x = atoi(val);
 					}
@@ -755,7 +762,13 @@ static void conference_parse_layouts(conference_obj_t *conference)
 					if ((val = switch_xml_attr(x_image, "reservation_id"))) {
 						res_id = val;
 					}
-									
+				
+					if ((val = switch_xml_attr(x_image, "audio-position"))) {
+						audio_position = val;
+					}
+				
+
+					
 					if (x < 0 || y < 0 || scale < 0 || !name) {
 						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid image\n");
 						continue;
@@ -770,7 +783,11 @@ static void conference_parse_layouts(conference_obj_t *conference)
 					if (res_id) {
 						lnode->images[lnode->layers].res_id = switch_core_strdup(conference->pool, res_id);
 					}
-					
+
+					if (audio_position) {
+						lnode->images[lnode->layers].audio_position = switch_core_strdup(conference->pool, audio_position);
+					}
+
 					lnode->layers++;
 				}
 
@@ -1005,15 +1022,99 @@ static void set_canvas_bgcolor(mcu_canvas_t *canvas, char *color)
 	reset_image(canvas->img, &canvas->bgcolor);
 }
 
+static void detach_video_layer(conference_member_t *member)
+{
+	mcu_layer_t *layer = NULL;
+
+	if (!member->conference->canvas || member->video_layer_id < 0) {
+		return;
+	}
+
+	layer = &member->conference->canvas->layers[member->video_layer_id];
+
+	if (layer->geometry.audio_position) {
+		conf_api_sub_position(member, NULL, "0:0:0");
+	}
+
+	switch_mutex_lock(member->conference->canvas->mutex);
+	reset_layer(member->conference->canvas, layer);
+	member->conference->canvas->layers_used--;
+	layer->member_id = 0;
+	member->video_layer_id = -1;
+	switch_mutex_unlock(member->conference->canvas->mutex);
+}
+
+static switch_status_t attach_video_layer(conference_member_t *member, int idx)
+{
+	mcu_layer_t *layer = NULL;
+	conference_member_t *imember = NULL;
+	switch_channel_t *channel = NULL;
+	const char *res_id = NULL;
+	if (!member->session) abort();
+	
+	channel = switch_core_session_get_channel(member->session);
+	res_id = switch_channel_get_variable(channel, "video_reservation_id");
+	
+
+	layer = &member->conference->canvas->layers[idx];
+
+	if (layer->member_id && layer->member_id == member->id) return SWITCH_STATUS_BREAK; /* no op */
+
+	if (layer->geometry.res_id || res_id) {
+		if (!layer->geometry.res_id || !res_id || strcmp(layer->geometry.res_id, res_id)) {
+			return SWITCH_STATUS_FALSE;
+		}
+	}
+	
+	switch_mutex_lock(member->conference->canvas->mutex);
+
+	if (layer->member_id && (imember = conference_member_get(member->conference, layer->member_id))) {
+		detach_video_layer(imember);
+		switch_thread_rwlock_unlock(imember->rwlock);
+	}
+
+	layer->member_id = member->id;
+	member->conference->canvas->layers_used++;
+	member->video_layer_id = idx;
+	switch_mutex_unlock(member->conference->canvas->mutex);
+
+	if (layer->geometry.audio_position) {
+		conf_api_sub_position(member, NULL, layer->geometry.audio_position);
+	}
+
+	return SWITCH_STATUS_SUCCESS;
+}
 
 static void init_canvas_layers(conference_obj_t *conference, layout_node_t *lnode)
 {
 	int i = 0;	
+	conference_member_t *member = NULL;
 
+	conference->canvas->layout_floor_id = -1;
+	
 	for (i = 0; i < lnode->layers; i++) {
-		conference->canvas->layers[i].geometry.x = lnode->images[i].x;
-		conference->canvas->layers[i].geometry.y = lnode->images[i].y;
-		conference->canvas->layers[i].geometry.scale = lnode->images[i].scale;
+		mcu_layer_t *layer = &conference->canvas->layers[i];
+
+		layer->geometry.x = lnode->images[i].x;
+		layer->geometry.y = lnode->images[i].y;
+		layer->geometry.scale = lnode->images[i].scale;
+		layer->geometry.floor = lnode->images[i].floor;
+		layer->idx = i;
+
+		if (layer->geometry.floor) {
+			conference->canvas->layout_floor_id = i;			
+		}
+
+		/* if we ever decided to reload layers config on demand the pointer assignment below  will lead to segs but we 
+		   only load them once forever per conference so these pointers are valid for the life of the conference */
+		layer->geometry.res_id = lnode->images[i].res_id;
+		layer->geometry.audio_position = lnode->images[i].audio_position;
+	}
+
+	if (conference->canvas->layout_floor_id > -1 && 
+		conference->video_floor_holder && (member = conference_member_get(conference, conference->video_floor_holder))) {
+		attach_video_layer(member, conference->canvas->layout_floor_id);
+		switch_thread_rwlock_unlock(member->rwlock);
 	}
 
 	conference->canvas->total_layers = lnode->layers;
@@ -1028,6 +1129,7 @@ static void init_canvas(conference_obj_t *conference, layout_node_t *lnode)
 		switch_mutex_init(&conference->canvas->mutex, SWITCH_MUTEX_NESTED, conference->pool);
 		switch_mutex_init(&conference->canvas->cond_mutex, SWITCH_MUTEX_NESTED, conference->pool);
 		switch_mutex_init(&conference->canvas->cond2_mutex, SWITCH_MUTEX_NESTED, conference->pool);
+		conference->canvas->layout_floor_id = -1;
 	}
 
 	switch_img_free(&conference->canvas->img);
@@ -1036,9 +1138,10 @@ static void init_canvas(conference_obj_t *conference, layout_node_t *lnode)
 
 	switch_assert(conference->canvas->img);
 
+	switch_mutex_lock(conference->canvas->mutex);
 	set_canvas_bgcolor(conference->canvas, conference->video_canvas_bgcolor);
-
 	init_canvas_layers(conference, lnode);
+	switch_mutex_unlock(conference->canvas->mutex);
 }
 
 static void destroy_canvas(mcu_canvas_t **canvasP) {
@@ -1136,9 +1239,11 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 	switch_timer_t timer = { 0 };
 	int i = 0;
 	int used = 0, remaining = 0;
-	uint32_t video_key_freq = 10000000;
+	uint32_t video_key_freq = 30000000;
 	switch_time_t last_key_time = 0;
 	mcu_layer_t *layer = NULL;
+	switch_frame_t write_frame = { 0 };
+	uint8_t *packet = switch_core_alloc(conference->pool, SWITCH_RECOMMENDED_BUFFER_SIZE);
 #ifdef TRACK_FPS
 	uint64_t frames = 0;
 	switch_time_t started = switch_micro_time_now();
@@ -1172,46 +1277,48 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 				continue;
 			}
 
+			if (switch_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) {
 
-			if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) {
-				switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ);
-				need_refresh = SWITCH_TRUE;
-			}
+				if (switch_channel_test_flag(ichannel, CF_VIDEO_REFRESH_REQ)) {
+					switch_channel_clear_flag(ichannel, CF_VIDEO_REFRESH_REQ);
+					need_refresh = SWITCH_TRUE;
+				}
 
-			if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) {
-				for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
-					if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) {
-						imember->video_codec_index = i;
-						imember->video_codec_id = check_codec->implementation->codec_id;
-						break;
+				if (imember->video_codec_index < 0 && (check_codec = switch_core_session_get_video_write_codec(imember->session))) {
+					for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
+						if (check_codec->implementation->codec_id == write_codecs[i]->codec.implementation->codec_id) {
+							imember->video_codec_index = i;
+							imember->video_codec_id = check_codec->implementation->codec_id;
+							break;
+						}
+					}
+
+					if (imember->video_codec_index < 0) {
+						write_codecs[i] = switch_core_alloc(conference->pool, sizeof(codec_set_t));
+					
+						if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec, conference->pool) == SWITCH_STATUS_SUCCESS) {
+							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, 
+											  "Setting up video write codec %s at slot %d\n", write_codecs[i]->codec.implementation->iananame, i);
+						
+							imember->video_codec_index = i;
+							imember->video_codec_id = check_codec->implementation->codec_id;
+
+							write_codecs[i]->frame.packet = switch_core_alloc(conference->pool, buflen);
+							write_codecs[i]->frame.data = ((uint8_t *)write_codecs[i]->frame.packet) + 12;
+							write_codecs[i]->frame.packetlen = 0;
+							write_codecs[i]->frame.buflen = buflen - 12;
+							switch_set_flag((&write_codecs[i]->frame), SFF_RAW_RTP);
+
+						}
 					}
 				}
 
 				if (imember->video_codec_index < 0) {
-					write_codecs[i] = switch_core_alloc(conference->pool, sizeof(codec_set_t));
-					
-					if (switch_core_codec_copy(check_codec, &write_codecs[i]->codec, conference->pool) == SWITCH_STATUS_SUCCESS) {
-						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, 
-										  "Setting up video write codec %s at slot %d\n", write_codecs[i]->codec.implementation->iananame, i);
-						
-						imember->video_codec_index = i;
-						imember->video_codec_id = check_codec->implementation->codec_id;
-
-						write_codecs[i]->frame.packet = switch_core_alloc(conference->pool, buflen);
-						write_codecs[i]->frame.data = ((uint8_t *)write_codecs[i]->frame.packet) + 12;
-						write_codecs[i]->frame.packetlen = 0;
-						write_codecs[i]->frame.buflen = buflen - 12;
-						switch_set_flag((&write_codecs[i]->frame), SFF_RAW_RTP);
-
-					}
+					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Codec Error\n");
+					continue;
 				}
 			}
 
-			if (imember->video_codec_index < 0) {
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Write Codec Error\n");
-				continue;
-			}
-
 			img = NULL;
 			size = 0;
 
@@ -1234,13 +1341,9 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 				used++;
 
 				switch_mutex_lock(conference->canvas->mutex);
-				
 				if (imember->video_layer_id > -1) {
 					if (imember->video_layer_id >= conference->canvas->total_layers) {
-						conference->canvas->layers[imember->video_layer_id].member_id = 0;
-						reset_layer(conference->canvas, &conference->canvas->layers[imember->video_layer_id]);
-						imember->video_layer_id = -1;
-						conference->canvas->layers_used--;
+						detach_video_layer(imember);
 					} else {
 						layer = &conference->canvas->layers[imember->video_layer_id];
 					}
@@ -1251,10 +1354,10 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 					for (i = 0; i < conference->canvas->total_layers; i++) {
 						layer = &conference->canvas->layers[i];
 						if (!layer->member_id) {
-							conference->canvas->layers[i].member_id = imember->id;
-							conference->canvas->layers_used++;
-							imember->video_layer_id = i;
-							break;
+							switch_status_t lstatus = attach_video_layer(imember, i);
+							if (lstatus == SWITCH_STATUS_SUCCESS || lstatus == SWITCH_STATUS_BREAK) {
+								break;
+							}
 						}
 					}
 				}
@@ -1266,8 +1369,6 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 					layer->cur_img = img;
 					scale_and_patch(conference, layer);
 				}
-
-
 			}
 
 			if (imember->session) {
@@ -1298,9 +1399,36 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread
 
 			switch_core_timer_sync(&timer);
 			
-			for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
-				write_codecs[i]->frame.img = conference->canvas->img;
-				write_canvas_image_to_codec_group(conference, write_codecs[i], i, timer.samplecount, need_refresh, need_keyframe);
+			if (switch_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) {
+				for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) {
+					write_codecs[i]->frame.img = conference->canvas->img;
+					write_canvas_image_to_codec_group(conference, write_codecs[i], i, timer.samplecount, need_refresh, need_keyframe);
+				}
+			} else {
+				switch_mutex_lock(conference->member_mutex);
+				for (imember = conference->members; imember; imember = imember->next) {
+					switch_channel_t *ichannel = switch_core_session_get_channel(imember->session);
+
+					if (!imember->session || !switch_channel_test_flag(ichannel, CF_VIDEO) || 
+						switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS) {
+						continue;
+					}
+
+					switch_set_flag(&write_frame, SFF_RAW_RTP);
+					write_frame.img = conference->canvas->img;
+					write_frame.packet = packet;
+					write_frame.data = packet + 12;
+					write_frame.datalen = SWITCH_RECOMMENDED_BUFFER_SIZE - 12;
+					write_frame.buflen = write_frame.datalen;
+					write_frame.packetlen = SWITCH_RECOMMENDED_BUFFER_SIZE;
+
+					switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0);			
+			
+					if (imember->session) {
+						switch_core_session_rwunlock(imember->session);
+					}
+				}
+				switch_mutex_unlock(conference->member_mutex);
 			}
 		}
 
@@ -3023,7 +3151,7 @@ static switch_status_t conference_add_member(conference_obj_t *conference, confe
 			switch_set_flag_locked(member, MFLAG_ACK_VIDEO);
 		}
 
-		if (switch_test_flag(conference, CFLAG_DECODE_VIDEO)) {
+		if (switch_test_flag(conference, CFLAG_TRANSCODE_VIDEO)) {
 			switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ);
 		}
 
@@ -3240,6 +3368,15 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf
 			conference->last_video_floor_holder = conference->video_floor_holder;
 			
 			if (conference->last_video_floor_holder && (imember = conference_member_get(conference, conference->last_video_floor_holder))) {
+
+				if (member->conference->canvas) {
+					switch_mutex_lock(member->conference->canvas->mutex);
+					detach_video_layer(member);
+					detach_video_layer(imember);
+					attach_video_layer(member, conference->canvas->layout_floor_id);
+					switch_mutex_unlock(member->conference->canvas->mutex);
+				}
+
 				switch_core_session_request_video_refresh(imember->session);
 
 				if (switch_test_flag(imember, MFLAG_VIDEO_BRIDGE)) {
@@ -3247,7 +3384,7 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf
 				}		
 				switch_thread_rwlock_unlock(imember->rwlock);
 				imember = NULL;
-			}
+			} 
 			
 			old_member = conference->video_floor_holder;
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping video floor %d\n", old_member);
@@ -3265,6 +3402,10 @@ static void conference_set_video_floor_holder(conference_obj_t *conference, conf
 		}
 	}
 
+	if (member && conference->canvas && conference->canvas->layout_floor_id > -1) {
+		attach_video_layer(member, conference->canvas->layout_floor_id);
+	}
+	
 	if (member) {
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding video floor %s\n",
 						  switch_channel_get_name(member->channel));
@@ -3485,13 +3626,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
 
 	lock_member(member);
 
-	if (member->video_layer_id > -1 && member->conference->canvas) {
-		reset_layer(conference->canvas, &conference->canvas->layers[member->video_layer_id]);
-		switch_mutex_lock(conference->canvas->mutex);
-		conference->canvas->layers_used--;
-		conference->canvas->layers[member->video_layer_id].member_id = 0;
-		switch_mutex_unlock(conference->canvas->mutex);
-	}
+	detach_video_layer(member);
 
 	member_del_relationship(member, 0);
 
@@ -7278,7 +7413,7 @@ static switch_status_t conf_api_sub_auto_position(conference_obj_t *conference,
 static switch_status_t conf_api_sub_position(conference_member_t *member, switch_stream_handle_t *stream, void *data)
 {
 #ifndef OPENAL_POSITIONING
-	stream->write_function(stream, "-ERR not supported\n");
+	if (stream) stream->write_function(stream, "-ERR not supported\n");
 #else
 	switch_event_t *event;
 
@@ -9685,8 +9820,12 @@ static void set_cflags(const char *flags, uint32_t *f)
 				*f |= CFLAG_RFC4579;
 			} else if (!strcasecmp(argv[i], "auto-3d-position")) {
 				*f |= CFLAG_POSITIONAL;
-			} else if (!strcasecmp(argv[i], "decode-video")) {
-				*f |= CFLAG_DECODE_VIDEO;
+			} else if (!strcasecmp(argv[i], "decode-video") || !strcasecmp(argv[i], "transcode-video")) {
+				*f |= CFLAG_TRANSCODE_VIDEO;
+			} else if (!strcasecmp(argv[i], "minimize-video-encoding")) {
+				*f |= CFLAG_MINIMIZE_VIDEO_ENCODING;
+			} else if (!strcasecmp(argv[i], "mix-video")) {
+				*f |= CFLAG_VIDEO_MUXING;
 			}
 
 			
@@ -10780,6 +10919,7 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
 	char *video_layout_name = NULL;
 	char *video_canvas_size = NULL;
 	char *video_canvas_bgcolor = NULL;
+	char *video_codec_bandwidth = NULL;
 	uint32_t max_members = 0;
 	uint32_t announce_count = 0;
 	char *maxmember_sound = NULL;
@@ -10933,6 +11073,8 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
 				video_canvas_bgcolor= val;
 			} else if (!strcasecmp(var, "video-canvas-size") && !zstr(val)) {
 				video_canvas_size = val;
+			} else if (!strcasecmp(var, "video-codec-bandwidth") && !zstr(val)) {
+				video_codec_bandwidth = val;
 			} else if (!strcasecmp(var, "exit-sound") && !zstr(val)) {
 				exit_sound = val;
 			} else if (!strcasecmp(var, "alone-sound") && !zstr(val)) {
@@ -11116,6 +11258,10 @@ static conference_obj_t *conference_new(char *name, conf_xml_cfg_t cfg, switch_c
 	conference->broadcast_chat_messages = broadcast_chat_messages;
 	conference_parse_layouts(conference);
 	
+	if (video_codec_bandwidth) {
+		conference->video_codec_bandwidth = switch_parse_bandwidth_string(video_codec_bandwidth);
+	}
+
 	if (video_layout_name && !switch_core_hash_find(conference->layout_hash, video_layout_name)) {
 		video_layout_name = NULL;
 		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "invalid conference layout settings\n"); 
diff --git a/src/switch_core_media.c b/src/switch_core_media.c
index a807c4c777..ce10085cf4 100644
--- a/src/switch_core_media.c
+++ b/src/switch_core_media.c
@@ -2367,23 +2367,12 @@ static void switch_core_session_parse_codec_settings(switch_core_session_t *sess
 	case SWITCH_MEDIA_TYPE_VIDEO:
 		{
 			const char *bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth");
-			uint32_t bw = 0;
-			
+
 			if (!bwv) {
 				bwv = switch_channel_get_variable(session->channel, "rtp_video_max_bandwidth_out");
 			}
-
-
-			if (bwv && (bw = (uint32_t) atol(bwv))) {
-				if (switch_stristr("KB", bwv)) {
-					bw *= 8;
-				} else if (switch_stristr("mb", bwv)) {
-					bw *= 1024;
-				} else if (switch_stristr("MB", bwv)) {
-					bw *= 8192;
-				}
-				engine->codec_settings.video.bandwidth = bw;
-			}
+			
+			engine->codec_settings.video.bandwidth = switch_parse_bandwidth_string(bwv);
 		}
 		break;
 	default:
@@ -7291,26 +7280,12 @@ SWITCH_DECLARE(void) switch_core_media_gen_local_sdp(switch_core_session_t *sess
 					vbw = switch_channel_get_variable(smh->session->channel, "rtp_video_max_bandwidth_in");
 				}
 
-
-				if (vbw) {
-					int v = atoi(vbw);
-					bw = v;
-
-					if (switch_stristr("KB", vbw)) {
-						bw *= 8;
-					} else if (switch_stristr("mb", vbw)) {
-						bw *= 1024;
-					} else if (switch_stristr("MB", vbw)) {
-						bw *= 8192;
-					}
-
-				}
+				bw = switch_parse_bandwidth_string(vbw);
 				
 				if (bw > 0) {
 					switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=AS:%d\n", bw);
 					//switch_snprintf(buf + strlen(buf), SDPBUFLEN - strlen(buf), "b=TIAS:%d\n", bw);
 				}
-				
 
 				if (sdp_type == SDP_TYPE_REQUEST) {
 					fir++;
diff --git a/src/switch_vidderbuffer.c b/src/switch_vidderbuffer.c
index 9553ded9ab..07c83d1933 100644
--- a/src/switch_vidderbuffer.c
+++ b/src/switch_vidderbuffer.c
@@ -191,8 +191,8 @@ static inline void add_node(switch_vb_t *vb, switch_rtp_packet_t *packet, switch
 
 
 
-	if (vb->write_init && ((abs(htons(packet->header.seq) - htons(vb->highest_wrote_seq)) > 10) || 
-						   (abs(ntohl(node->packet.header.ts) - ntohl(vb->highest_wrote_ts)) > 270000))) {
+	if (vb->write_init && ((abs(htons(packet->header.seq) - htons(vb->highest_wrote_seq)) > 16) || 
+						   (abs(ntohl(node->packet.header.ts) - ntohl(vb->highest_wrote_ts)) > 900000))) {
 		vb_debug(vb, 2, "%s", "CHANGE DETECTED, PUNT\n");
 		switch_vb_reset(vb);
 	}
@@ -408,11 +408,9 @@ SWITCH_DECLARE(uint32_t) switch_vb_pop_nack(switch_vb_t *vb)
 		nack = (uint32_t) htons(least);
 		
 		for(i = 0; i < 16; i++) {
-			if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least + i))) {
+			if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(least + i + 1))) {
 				vb_debug(vb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1);
 				blp |= (1 << i);
-			} else {
-				break;
 			}
 		}
 
@@ -443,18 +441,17 @@ SWITCH_DECLARE(switch_status_t) switch_vb_put_packet(switch_vb_t *vb, switch_rtp
 	if (!want) want = got;
 	
 	if (got > want) {
+		vb_debug(vb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1);
+
 		for (i = want; i < got; i++) {
-			vb_debug(vb, 2, "MARK SEQ MISSING %u\n", i);
 			switch_core_inthash_insert(vb->missing_seq_hash, (uint32_t)htons(i), (void *)SWITCH_TRUE);
 		}
 	} else {
-		if (switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(got))) {
-			vb_debug(vb, 2, "MARK SEQ FOUND %u\n", got);
-		}
+		switch_core_inthash_delete(vb->missing_seq_hash, (uint32_t)htons(got));
 	}
 
 	if (got >= want) {
-		vb->next_seq = htons(ntohs(packet->header.seq) + 1);
+		vb->next_seq = htons(got + 1);
 	}
 
 	add_node(vb, packet, len);