Index: pjproject/trunk/pjmedia/src/pjmedia/conf_switch.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/conf_switch.c	(revision 3553)
+++ pjproject/trunk/pjmedia/src/pjmedia/conf_switch.c	(revision 3664)
@@ -24,8 +24,8 @@
 #include <pjmedia/silencedet.h>
 #include <pjmedia/sound_port.h>
-#include <pjmedia/stream.h>
 #include <pj/array.h>
 #include <pj/assert.h>
 #include <pj/log.h>
+#include <pj/math.h>
 #include <pj/pool.h>
 #include <pj/string.h>
@@ -81,4 +81,5 @@
     /* Shortcut for port info. */
     pjmedia_port_info	*info;
+    unsigned		 samples_per_frame;
 
     /* Calculated signal levels: */
@@ -124,5 +125,5 @@
 /* Prototypes */
 static pj_status_t put_frame(pjmedia_port *this_port, 
-			     const pjmedia_frame *frame);
+			     pjmedia_frame *frame);
 static pj_status_t get_frame(pjmedia_port *this_port, 
 			     pjmedia_frame *frame);
@@ -167,4 +168,5 @@
     conf_port->port = port;
     conf_port->info = &port->info;
+    conf_port->samples_per_frame= PJMEDIA_PINFO_SAMPLES_PER_FRAME(&port->info);
 
     /* Init pjmedia_frame structure in the TX buffer. */
@@ -505,4 +507,5 @@
     struct conf_port *src_port, *dst_port;
     pj_bool_t start_sound = PJ_FALSE;
+    pjmedia_audio_format_detail *src_afd, *dst_afd;
     unsigned i;
 
@@ -524,7 +527,10 @@
     }
 
+    src_afd = pjmedia_format_get_audio_format_detail(&src_port->info->fmt, 1);
+    dst_afd = pjmedia_format_get_audio_format_detail(&dst_port->info->fmt, 1);
+
     /* Format must match. */
-    if (src_port->info->format.id != dst_port->info->format.id ||
-	src_port->info->format.bitrate != dst_port->info->format.bitrate) 
+    if (src_port->info->fmt.id != dst_port->info->fmt.id ||
+	src_afd->avg_bps != dst_afd->avg_bps)
     {
 	pj_mutex_unlock(conf->mutex);
@@ -533,5 +539,5 @@
 
     /* Clock rate must match. */
-    if (src_port->info->clock_rate != dst_port->info->clock_rate) {
+    if (src_afd->clock_rate != dst_afd->clock_rate) {
 	pj_mutex_unlock(conf->mutex);
 	return PJMEDIA_ENCCLOCKRATE;
@@ -539,5 +545,5 @@
 
     /* Channel count must match. */
-    if (src_port->info->channel_count != dst_port->info->channel_count) {
+    if (src_afd->channel_count != dst_afd->channel_count) {
 	pj_mutex_unlock(conf->mutex);
 	return PJMEDIA_ENCCLOCKRATE;
@@ -545,8 +551,6 @@
 
     /* Source and sink ptime must be equal or a multiplication factor. */
-    if ((src_port->info->samples_per_frame % 
-	 dst_port->info->samples_per_frame != 0) &&
-        (dst_port->info->samples_per_frame % 
-         src_port->info->samples_per_frame != 0))
+    if ((src_afd->frame_time_usec % dst_afd->frame_time_usec != 0) &&
+        (dst_afd->frame_time_usec % src_afd->frame_time_usec != 0))
     {
 	pj_mutex_unlock(conf->mutex);
@@ -830,4 +834,5 @@
 {
     struct conf_port *conf_port;
+    const pjmedia_audio_format_detail *afd;
 
     /* Check arguments */
@@ -843,4 +848,6 @@
 	return PJ_EINVAL;
     }
+
+    afd = pjmedia_format_get_audio_format_detail(&conf_port->info->fmt, 1);
 
     pj_bzero(info, sizeof(pjmedia_conf_port_info));
@@ -853,9 +860,9 @@
     info->listener_slots = conf_port->listener_slots;
     info->transmitter_cnt = conf_port->transmitter_cnt;
-    info->clock_rate = conf_port->info->clock_rate;
-    info->channel_count = conf_port->info->channel_count;
-    info->samples_per_frame = conf_port->info->samples_per_frame;
-    info->bits_per_sample = conf_port->info->bits_per_sample;
-    info->format = conf_port->port->info.format;
+    info->clock_rate = afd->clock_rate;
+    info->channel_count = afd->channel_count;
+    info->samples_per_frame = conf_port->samples_per_frame;
+    info->bits_per_sample = afd->bits_per_sample;
+    info->format = conf_port->port->info.fmt;
     info->tx_adj_level = conf_port->tx_adj_level - NORMAL_LEVEL;
     info->rx_adj_level = conf_port->rx_adj_level - NORMAL_LEVEL;
@@ -961,5 +968,5 @@
 
     /* Level adjustment is applicable only for ports that work with raw PCM. */
-    PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16,
+    PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,
 		     PJ_EIGNORED);
 
@@ -1003,5 +1010,5 @@
 
     /* Level adjustment is applicable only for ports that work with raw PCM. */
-    PJ_ASSERT_RETURN(conf_port->info->format.id == PJMEDIA_FORMAT_L16,
+    PJ_ASSERT_RETURN(conf_port->info->fmt.id == PJMEDIA_FORMAT_L16,
 		     PJ_EIGNORED);
 
@@ -1047,5 +1054,5 @@
 	     * samples per frame.
 	     */
-	    if (f_dst->samples_cnt >= cport_dst->info->samples_per_frame)
+	    if (f_dst->samples_cnt >= cport_dst->samples_per_frame)
 	    {
 		if (cport_dst->slot) {
@@ -1059,6 +1066,6 @@
 
 		/* Update TX timestamp. */
-		pj_add_timestamp32(&cport_dst->ts_tx, 
-				   cport_dst->info->samples_per_frame);
+		pj_add_timestamp32(&cport_dst->ts_tx,
+				   cport_dst->samples_per_frame);
 	    }
 	}
@@ -1076,5 +1083,5 @@
 	    /* Copy frame to listener's TX buffer. */
 	    nsamples_to_copy = f_end - f_start;
-	    nsamples_req = cport_dst->info->samples_per_frame - 
+	    nsamples_req = cport_dst->samples_per_frame -
 			  (frm_dst->size>>1);
 	    if (nsamples_to_copy > nsamples_req)
@@ -1113,5 +1120,5 @@
 	     * samples per frame.
 	     */
-	    if ((frm_dst->size >> 1) == cport_dst->info->samples_per_frame)
+	    if ((frm_dst->size >> 1) == cport_dst->samples_per_frame)
 	    {
 		if (cport_dst->slot) {
@@ -1124,5 +1131,5 @@
 		/* Update TX timestamp. */
 		pj_add_timestamp32(&cport_dst->ts_tx, 
-				   cport_dst->info->samples_per_frame);
+				   cport_dst->samples_per_frame);
 	    }
 	}
@@ -1132,5 +1139,5 @@
 	/* Check port format. */
 	if (cport_dst->port &&
-	    cport_dst->port->info.format.id == PJMEDIA_FORMAT_L16)
+	    cport_dst->port->info.fmt.id == PJMEDIA_FORMAT_L16)
 	{
 	    /* When there is already some samples in listener's TX buffer, 
@@ -1139,9 +1146,9 @@
 	    if (frm_dst->size != 0) {
 		pjmedia_zero_samples((pj_int16_t*)frm_dst->buf,
-				     cport_dst->info->samples_per_frame - 
+				     cport_dst->samples_per_frame -
 				     (frm_dst->size>>1));
 
 		frm_dst->type = PJMEDIA_FRAME_TYPE_AUDIO;
-		frm_dst->size = cport_dst->info->samples_per_frame << 1;
+		frm_dst->size = cport_dst->samples_per_frame << 1;
 		if (cport_dst->slot) {
 		    pjmedia_port_put_frame(cport_dst->port, frm_dst);
@@ -1153,5 +1160,5 @@
 		/* Update TX timestamp. */
 		pj_add_timestamp32(&cport_dst->ts_tx, 
-				   cport_dst->info->samples_per_frame);
+				   cport_dst->samples_per_frame);
 	    }
 	} else {
@@ -1161,5 +1168,5 @@
 		frm_dst->type = PJMEDIA_FRAME_TYPE_EXTENDED;
 		pjmedia_frame_ext_append_subframe(f_dst, NULL, 0, (pj_uint16_t)
-		    (cport_dst->info->samples_per_frame - f_dst->samples_cnt));
+		    (cport_dst->samples_per_frame - f_dst->samples_cnt));
 		if (cport_dst->slot) {
 		    pjmedia_port_put_frame(cport_dst->port, frm_dst);
@@ -1172,5 +1179,5 @@
 		/* Update TX timestamp. */
 		pj_add_timestamp32(&cport_dst->ts_tx, 
-				   cport_dst->info->samples_per_frame);
+				   cport_dst->samples_per_frame);
 	    }
 	}
@@ -1186,5 +1193,5 @@
 
 	    /* Update TX timestamp. */
-	    pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->info->samples_per_frame);
+	    pj_add_timestamp32(&cport_dst->ts_tx, cport_dst->samples_per_frame);
 	}
     }
@@ -1212,4 +1219,5 @@
     for (i=1, ci=1; i<conf->max_ports && ci<conf->port_cnt; ++i) {
 	struct conf_port *cport = conf->ports[i];
+	unsigned master_samples_per_frame;
 
 	/* Skip empty port. */
@@ -1220,7 +1228,9 @@
 	++ci;
 
+	master_samples_per_frame = PJMEDIA_PINFO_SAMPLES_PER_FRAME(
+					&conf->master_port->info);
+
 	/* Update clock of the port. */
-	pj_add_timestamp32(&cport->ts_clock, 
-			   conf->master_port->info.samples_per_frame);
+	pj_add_timestamp32(&cport->ts_clock, master_samples_per_frame);
 
 	/* Skip if we're not allowed to receive from this port or 
@@ -1231,6 +1241,5 @@
 	{
 	    cport->rx_level = 0;
-	    pj_add_timestamp32(&cport->ts_rx, 
-			       conf->master_port->info.samples_per_frame);
+	    pj_add_timestamp32(&cport->ts_rx, master_samples_per_frame);
 	    continue;
 	}
@@ -1246,8 +1255,8 @@
 	    pj_int32_t level = 0;
 
-	    pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
+	    pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);
 	    
 	    f->buf = &conf->buf[sizeof(pjmedia_frame)];
-	    f->size = cport->info->samples_per_frame<<1;
+	    f->size = cport->samples_per_frame<<1;
 
 	    /* Get frame from port. */
@@ -1303,5 +1312,5 @@
 		if (listener->tx_setting == PJMEDIA_PORT_DISABLE) {
 		    pj_add_timestamp32(&listener->ts_tx, 
-				       listener->info->samples_per_frame);
+				       listener->samples_per_frame);
 		    listener->tx_level = 0;
 		    continue;
@@ -1362,5 +1371,5 @@
 
 		    pjmedia_port_put_frame(cport->port, &tmp_f);
-		    pj_add_timestamp32(&cport->ts_tx, cport->info->samples_per_frame);
+		    pj_add_timestamp32(&cport->ts_tx, cport->samples_per_frame);
 		}
 	    }
@@ -1381,5 +1390,5 @@
 	    unsigned samples_per_subframe;
 	    
-	    if (f_src_->samples_cnt < this_cport->info->samples_per_frame) {
+	    if (f_src_->samples_cnt < this_cport->samples_per_frame) {
 		f_dst->base.type = PJMEDIA_FRAME_TYPE_NONE;
 		f_dst->samples_cnt = 0;
@@ -1394,5 +1403,5 @@
 
 
-	    while (f_dst->samples_cnt < this_cport->info->samples_per_frame) {
+	    while (f_dst->samples_cnt < this_cport->samples_per_frame) {
 		sf = pjmedia_frame_ext_get_subframe(f_src_, i++);
 		pj_assert(sf);
@@ -1405,5 +1414,5 @@
 
 	} else if (f_src->type == PJMEDIA_FRAME_TYPE_AUDIO) {
-	    if ((f_src->size>>1) < this_cport->info->samples_per_frame) {
+	    if ((f_src->size>>1) < this_cport->samples_per_frame) {
 		frame->type = PJMEDIA_FRAME_TYPE_NONE;
 		frame->size = 0;
@@ -1413,6 +1422,6 @@
 	    pjmedia_copy_samples((pj_int16_t*)frame->buf, 
 				 (pj_int16_t*)f_src->buf, 
-				 this_cport->info->samples_per_frame);
-	    frame->size = this_cport->info->samples_per_frame << 1;
+				 this_cport->samples_per_frame);
+	    frame->size = this_cport->samples_per_frame << 1;
 
 	    /* Shift left TX buffer. */
@@ -1421,5 +1430,5 @@
 		pjmedia_move_samples((pj_int16_t*)f_src->buf,
 				     (pj_int16_t*)f_src->buf + 
-				     this_cport->info->samples_per_frame,
+				     this_cport->samples_per_frame,
 				     f_src->size >> 1);
 	} else { /* PJMEDIA_FRAME_TYPE_NONE */
@@ -1443,5 +1452,5 @@
  */
 static pj_status_t put_frame(pjmedia_port *this_port, 
-			     const pjmedia_frame *f)
+			     pjmedia_frame *f)
 {
     pjmedia_conf *conf = (pjmedia_conf*) this_port->port_data.pdata;
@@ -1461,5 +1470,5 @@
     }
 
-    pj_add_timestamp32(&cport->ts_rx, cport->info->samples_per_frame);
+    pj_add_timestamp32(&cport->ts_rx, cport->samples_per_frame);
     
     /* Skip if this port is muted/disabled. */
@@ -1527,5 +1536,5 @@
 	if (listener->tx_setting == PJMEDIA_PORT_DISABLE) {
 	    pj_add_timestamp32(&listener->ts_tx, 
-			       listener->info->samples_per_frame);
+			       listener->samples_per_frame);
 	    listener->tx_level = 0;
 	    continue;
@@ -1535,5 +1544,5 @@
 	if (listener == cport) {
 	    pj_add_timestamp32(&listener->ts_tx, 
-			       listener->info->samples_per_frame);
+			       listener->samples_per_frame);
 	    listener->tx_level = 0;
 	    continue;
