Index: /pjproject/trunk/pjmedia/include/pjmedia/codec.h
===================================================================
--- /pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 873)
+++ /pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 874)
@@ -254,5 +254,7 @@
        unsigned	   channel_cnt;		/**< Channel count.		    */
        pj_uint32_t avg_bps;		/**< Average bandwidth in bits/sec  */
-       pj_uint16_t frm_ptime;		/**< Base frame ptime in msec.	    */
+       pj_uint16_t frm_ptime;		/**< Decoder frame ptime in msec.   */
+       pj_uint16_t enc_ptime;		/**< Encoder ptime, or zero if it's
+					     equal to decoder ptime.	    */
        pj_uint8_t  pcm_bits_per_sample;	/**< Bits/sample in the PCM side    */
        pj_uint8_t  pt;			/**< Payload type.		    */
@@ -307,5 +309,8 @@
 
     /** 
-     * Open the codec and initialize with the specified parameter..
+     * Open the codec and initialize with the specified parameter.
+     * Upon successful initialization, the codec may modify the parameter
+     * and fills in the unspecified values (such as enc_ptime, when
+     * encoder ptime is different than decoder ptime).
      *
      * @param codec	The codec instance.
@@ -315,5 +320,5 @@
      */
     pj_status_t	(*open)(pjmedia_codec *codec, 
-			const pjmedia_codec_param *param );
+			pjmedia_codec_param *param );
 
     /** 
Index: /pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c	(revision 874)
@@ -55,5 +55,5 @@
 				    pj_pool_t *pool );
 static pj_status_t  gsm_codec_open( pjmedia_codec *codec, 
-				    const pjmedia_codec_param *attr );
+				    pjmedia_codec_param *attr );
 static pj_status_t  gsm_codec_close( pjmedia_codec *codec );
 static pj_status_t  gsm_codec_modify(pjmedia_codec *codec, 
@@ -389,5 +389,5 @@
  */
 static pj_status_t gsm_codec_open( pjmedia_codec *codec, 
-				   const pjmedia_codec_param *attr )
+				   pjmedia_codec_param *attr )
 {
     struct gsm_data *gsm_data = codec->codec_data;
@@ -441,5 +441,5 @@
 
     pj_assert(gsm_data != NULL);
-    pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL);
+    pj_assert(gsm_data->encoder != NULL && gsm_data->decoder != NULL);
 
     gsm_data->vad_enabled = (attr->setting.vad != 0);
Index: /pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c	(revision 874)
@@ -64,5 +64,5 @@
 				    pj_pool_t *pool );
 static pj_status_t  ilbc_codec_open(pjmedia_codec *codec, 
-				    const pjmedia_codec_param *attr );
+				    pjmedia_codec_param *attr );
 static pj_status_t  ilbc_codec_close(pjmedia_codec *codec );
 static pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, 
@@ -365,8 +365,7 @@
  */
 static pj_status_t ilbc_codec_open(pjmedia_codec *codec, 
-				   const pjmedia_codec_param *param_attr )
+				   pjmedia_codec_param *attr )
 {
     struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
-    pjmedia_codec_param attr_copy, *attr;
     pj_status_t status;
 
@@ -374,8 +373,4 @@
     pj_assert(ilbc_codec->enc_ready == PJ_FALSE && 
 	      ilbc_codec->dec_ready == PJ_FALSE);
-
-    /* Copy param to temporary location since we need to modify fmtp_mode */
-    pj_memcpy(&attr_copy, param_attr, sizeof(*param_attr));
-    attr = &attr_copy;
 
     /* Decoder mode must be set */
@@ -392,4 +387,11 @@
     PJ_ASSERT_RETURN(attr->setting.enc_fmtp_mode==20 ||
 		     attr->setting.enc_fmtp_mode==30, PJMEDIA_CODEC_EINMODE);
+
+    /* Update enc_ptime in the param */
+    if (attr->setting.enc_fmtp_mode != attr->setting.dec_fmtp_mode) {
+	attr->info.enc_ptime = attr->setting.enc_fmtp_mode;
+    } else {
+	attr->info.enc_ptime = 0;
+    }
 
     /* Create enc */
Index: /pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c	(revision 874)
@@ -60,5 +60,5 @@
 			       pj_pool_t *pool );
 static pj_status_t  l16_open( pjmedia_codec *codec, 
-			       const pjmedia_codec_param *attr );
+			      pjmedia_codec_param *attr );
 static pj_status_t  l16_close( pjmedia_codec *codec );
 static pj_status_t  l16_modify(pjmedia_codec *codec, 
@@ -490,5 +490,5 @@
 
 static pj_status_t l16_open(pjmedia_codec *codec, 
-			    const pjmedia_codec_param *attr )
+			    pjmedia_codec_param *attr )
 {
     /* Nothing to do.. */
Index: /pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 874)
@@ -60,5 +60,5 @@
 				    pj_pool_t *pool );
 static pj_status_t  spx_codec_open( pjmedia_codec *codec, 
-				    const pjmedia_codec_param *attr );
+				    pjmedia_codec_param *attr );
 static pj_status_t  spx_codec_close( pjmedia_codec *codec );
 static pj_status_t  spx_codec_modify(pjmedia_codec *codec, 
@@ -548,5 +548,5 @@
  */
 static pj_status_t spx_codec_open( pjmedia_codec *codec, 
-				   const pjmedia_codec_param *attr )
+				   pjmedia_codec_param *attr )
 {
     struct spx_private *spx;
Index: /pjproject/trunk/pjmedia/src/pjmedia/g711.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/g711.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia/g711.c	(revision 874)
@@ -63,5 +63,5 @@
 			       pj_pool_t *pool );
 static pj_status_t  g711_open( pjmedia_codec *codec, 
-			       const pjmedia_codec_param *attr );
+			       pjmedia_codec_param *attr );
 static pj_status_t  g711_close( pjmedia_codec *codec );
 static pj_status_t  g711_modify(pjmedia_codec *codec, 
@@ -398,5 +398,5 @@
 
 static pj_status_t g711_open(pjmedia_codec *codec, 
-			     const pjmedia_codec_param *attr )
+			     pjmedia_codec_param *attr )
 {
     struct g711_private *priv = codec->codec_data;
Index: /pjproject/trunk/pjmedia/src/pjmedia/stream.c
===================================================================
--- /pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 873)
+++ /pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 874)
@@ -89,4 +89,15 @@
     pjmedia_codec	    *codec;	    /**< Codec instance being used. */
     pjmedia_codec_param	     codec_param;   /**< Codec param.		    */
+    pj_int16_t		    *enc_buf;	    /**< Encoding buffer, when enc's
+						 ptime is different than dec.
+						 Otherwise it's NULL.	    */
+
+    unsigned		     enc_samples_per_frame;
+    unsigned		     enc_buf_size;  /**< Encoding buffer size, in
+						 samples.		    */
+    unsigned		     enc_buf_pos;   /**< First position in buf.	    */
+    unsigned		     enc_buf_count; /**< Number of samples in the
+						 encoding buffer.	    */
+
     unsigned		     vad_enabled;   /**< VAD enabled in param.	    */
     unsigned		     frame_size;    /**< Size of encoded base frame.*/
@@ -443,4 +454,230 @@
 
 /**
+ * Rebuffer the frame when encoder and decoder has different ptime
+ * (such as when different iLBC modes are used by local and remote)
+ */
+static void rebuffer(pjmedia_stream *stream,
+		     pjmedia_frame *frame)
+{
+    /* How many samples are needed */
+    unsigned count;
+
+    /* Normalize frame */
+    if (frame->type != PJMEDIA_FRAME_TYPE_AUDIO)
+	frame->size = 0;
+
+    /* Remove used frame from the buffer. */
+    if (stream->enc_buf_pos) {
+	if (stream->enc_buf_count) {
+	    pj_memmove(stream->enc_buf,
+		       stream->enc_buf + stream->enc_buf_pos,
+		       (stream->enc_buf_count << 1));
+	}
+	stream->enc_buf_pos = 0;
+    }
+
+    /* Make sure we have space to store the new frame */
+    pj_assert(stream->enc_buf_count + (frame->size >> 1) <
+		stream->enc_buf_size);
+
+    /* Append new frame to the buffer */
+    if (frame->size) {
+	pj_memcpy(stream->enc_buf + stream->enc_buf_count,
+		  frame->buf, frame->size);
+	stream->enc_buf_count += (frame->size >> 1);
+    }
+
+    /* How many samples are needed */
+    count = stream->codec_param.info.enc_ptime * 
+		stream->port.info.clock_rate / 1000;
+
+    /* See if we have enough samples */
+    if (stream->enc_buf_count >= count) {
+
+	frame->type = PJMEDIA_FRAME_TYPE_AUDIO;
+	frame->buf = stream->enc_buf;
+	frame->size = (count << 1);
+
+	stream->enc_buf_pos = count;
+	stream->enc_buf_count -= count;
+
+    } else {
+	/* We don't have enough samples */
+	frame->type = PJMEDIA_FRAME_TYPE_NONE;
+    }
+}
+
+
+/**
+ * put_frame_imp()
+ */
+static pj_status_t put_frame_imp( pjmedia_port *port, 
+				  const pjmedia_frame *frame )
+{
+    pjmedia_stream *stream = port->port_data.pdata;
+    pjmedia_channel *channel = stream->enc;
+    pj_status_t status = 0;
+    pjmedia_frame frame_out;
+    unsigned ts_len, samples_per_frame;
+    void *rtphdr;
+    int rtphdrlen;
+
+
+    /* Don't do anything if stream is paused */
+    if (channel->paused) {
+	stream->enc_buf_pos = stream->enc_buf_count = 0;
+	return PJ_SUCCESS;
+    }
+
+    /* Number of samples in the frame */
+    if (frame->type == PJMEDIA_FRAME_TYPE_AUDIO)
+	ts_len = (frame->size >> 1);
+    else
+	ts_len = 0;
+
+    /* Increment transmit duration */
+    stream->tx_duration += ts_len;
+
+    /* Init frame_out buffer. */
+    frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
+    frame_out.size = 0;
+
+    /* Calculate number of samples per frame */
+    samples_per_frame = stream->enc_samples_per_frame;
+
+
+    /* If we have DTMF digits in the queue, transmit the digits. 
+     * Otherwise encode the PCM buffer.
+     */
+    if (stream->tx_dtmf_count) {
+
+	create_dtmf_payload(stream, &frame_out);
+
+	/* Encapsulate. */
+	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
+					 stream->tx_event_pt, 0, 
+					 frame_out.size, ts_len, 
+					 (const void**)&rtphdr, 
+					 &rtphdrlen);
+
+    } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) {
+	unsigned ts;
+
+	/* Repeatedly call encode if there are multiple frames to be
+	 * sent.
+	 */
+
+	for (ts=0; ts<ts_len; ts += samples_per_frame) {
+	    pjmedia_frame tmp_out_frame, tmp_in_frame;
+	    unsigned bytes_per_sample, max_size;
+
+	    /* Nb of bytes in PCM sample */
+	    bytes_per_sample = stream->codec_param.info.pcm_bits_per_sample/8;
+
+	    /* Split original PCM input frame into base frame size */
+	    tmp_in_frame.buf = ((char*)frame->buf) + ts * bytes_per_sample;
+	    tmp_in_frame.size = samples_per_frame * bytes_per_sample;
+	    tmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
+
+	    /* Set output frame position */
+	    tmp_out_frame.buf = ((char*)frame_out.buf) + frame_out.size;
+
+	    max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr) -
+		       frame_out.size;
+
+	    /* Encode! */
+	    status = stream->codec->op->encode( stream->codec, &tmp_in_frame, 
+						max_size, &tmp_out_frame);
+	    if (status != PJ_SUCCESS) {
+		LOGERR_((stream->port.info.name.ptr, 
+			"Codec encode() error", status));
+		return status;
+	    }
+
+	    /* tmp_out_frame.size may be zero for silence frame. */
+	    frame_out.size += tmp_out_frame.size;
+
+	    /* Stop processing next PCM frame when encode() returns either 
+	     * CNG frame or NULL frame.
+	     */
+	    if (tmp_out_frame.type!=PJMEDIA_FRAME_TYPE_AUDIO || 
+		tmp_out_frame.size==0) 
+	    {
+		break;
+	    }
+
+	}
+
+	/* Encapsulate. */
+	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
+					 channel->pt, 0, 
+					 frame_out.size, ts_len, 
+					 (const void**)&rtphdr, 
+					 &rtphdrlen);
+    } else {
+
+	/* Just update RTP session's timestamp. */
+	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
+					 0, 0, 
+					 0, ts_len, 
+					 (const void**)&rtphdr, 
+					 &rtphdrlen);
+
+    }
+
+    if (status != PJ_SUCCESS) {
+	LOGERR_((stream->port.info.name.ptr, 
+		"RTP encode_rtp() error", status));
+	return status;
+    }
+
+    /* Check if now is the time to transmit RTCP SR/RR report. 
+     * We only do this when stream direction is not "decoding only", because
+     * when it is, check_tx_rtcp() will be handled by get_frame().
+     */
+    if (stream->dir != PJMEDIA_DIR_DECODING) {
+	check_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));
+    }
+
+    /* Do nothing if we have nothing to transmit */
+    if (frame_out.size == 0) {
+	if (stream->is_streaming) {
+	    PJ_LOG(5,(stream->port.info.name.ptr,"Starting silence"));
+	    stream->is_streaming = PJ_FALSE;
+	}
+
+	return PJ_SUCCESS;
+    }
+
+
+    /* Copy RTP header to the beginning of packet */
+    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
+
+
+    /* Set RTP marker bit if currently not streaming */
+    if (stream->is_streaming == PJ_FALSE) {
+	pjmedia_rtp_hdr *rtp = channel->out_pkt;
+
+	rtp->m = 1;
+	PJ_LOG(5,(stream->port.info.name.ptr,"Start talksprut.."));
+    }
+
+    stream->is_streaming = PJ_TRUE;
+
+    /* Send the RTP packet to the transport. */
+    (*stream->transport->op->send_rtp)(stream->transport,
+				       channel->out_pkt, 
+				       frame_out.size + 
+					    sizeof(pjmedia_rtp_hdr));
+
+
+    /* Update stat */
+    pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);
+
+    return PJ_SUCCESS;
+}
+
+
+/**
  * put_frame()
  *
@@ -453,34 +690,8 @@
 {
     pjmedia_stream *stream = port->port_data.pdata;
-    pjmedia_channel *channel = stream->enc;
-    pj_status_t status = 0;
-    struct pjmedia_frame frame_out;
-    unsigned ts_len, samples_per_frame;
     pjmedia_frame tmp_in_frame;
-    void *rtphdr;
-    int rtphdrlen;
-
-
-    /* Don't do anything if stream is paused */
-    if (channel->paused)
-	return PJ_SUCCESS;
-
-
-    /* Number of samples in the frame */
-    //ts_len = frame->size / 2;
-    ts_len = port->info.samples_per_frame;
-
-    /* Increment transmit duration */
-    stream->tx_duration += ts_len;
-
-    /* Init frame_out buffer. */
-    frame_out.buf = ((char*)channel->out_pkt) + sizeof(pjmedia_rtp_hdr);
-    frame_out.size = 0;
-
-    /* Calculate number of samples per frame */
-    samples_per_frame = stream->codec_param.info.frm_ptime *
-			stream->codec_param.info.clock_rate *
-			stream->codec_param.info.channel_cnt /
-			1000;
+    unsigned samples_per_frame;
+
+    samples_per_frame = stream->enc_samples_per_frame;
 
     /* If VAD is temporarily disabled during creation, feed zero PCM frame
@@ -500,133 +711,4 @@
     }
 
-
-    /* If we have DTMF digits in the queue, transmit the digits. 
-     * Otherwise encode the PCM buffer.
-     */
-    if (stream->tx_dtmf_count) {
-
-	create_dtmf_payload(stream, &frame_out);
-
-	/* Encapsulate. */
-	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
-					 stream->tx_event_pt, 0, 
-					 frame_out.size, ts_len, 
-					 (const void**)&rtphdr, 
-					 &rtphdrlen);
-
-    } else if (frame->type != PJMEDIA_FRAME_TYPE_NONE) {
-	unsigned ts;
-
-	/* Repeatedly call encode if there are multiple frames to be
-	 * sent.
-	 */
-
-	for (ts=0; ts<ts_len; ts += samples_per_frame) {
-	    pjmedia_frame tmp_out_frame, tmp_in_frame;
-	    unsigned bytes_per_sample, max_size;
-
-	    /* Nb of bytes in PCM sample */
-	    bytes_per_sample = stream->codec_param.info.pcm_bits_per_sample/8;
-
-	    /* Split original PCM input frame into base frame size */
-	    tmp_in_frame.buf = ((char*)frame->buf) + ts * bytes_per_sample;
-	    tmp_in_frame.size = samples_per_frame * bytes_per_sample;
-	    tmp_in_frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
-
-	    /* Set output frame position */
-	    tmp_out_frame.buf = ((char*)frame_out.buf) + frame_out.size;
-
-	    max_size = channel->out_pkt_size - sizeof(pjmedia_rtp_hdr) -
-		       frame_out.size;
-
-	    /* Encode! */
-	    status = stream->codec->op->encode( stream->codec, &tmp_in_frame, 
-						max_size, &tmp_out_frame);
-	    if (status != PJ_SUCCESS) {
-		LOGERR_((stream->port.info.name.ptr, 
-			"Codec encode() error", status));
-		return status;
-	    }
-
-	    /* tmp_out_frame.size may be zero for silence frame. */
-	    frame_out.size += tmp_out_frame.size;
-
-	    /* Stop processing next PCM frame when encode() returns either 
-	     * CNG frame or NULL frame.
-	     */
-	    if (tmp_out_frame.type!=PJMEDIA_FRAME_TYPE_AUDIO || 
-		tmp_out_frame.size==0) 
-	    {
-		break;
-	    }
-
-	}
-
-	/* Encapsulate. */
-	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
-					 channel->pt, 0, 
-					 frame_out.size, ts_len, 
-					 (const void**)&rtphdr, 
-					 &rtphdrlen);
-    } else {
-
-	/* Just update RTP session's timestamp. */
-	status = pjmedia_rtp_encode_rtp( &channel->rtp, 
-					 0, 0, 
-					 0, ts_len, 
-					 (const void**)&rtphdr, 
-					 &rtphdrlen);
-
-    }
-
-    if (status != PJ_SUCCESS) {
-	LOGERR_((stream->port.info.name.ptr, 
-		"RTP encode_rtp() error", status));
-	return status;
-    }
-
-    /* Check if now is the time to transmit RTCP SR/RR report. 
-     * We only do this when stream direction is not "decoding only", because
-     * when it is, check_tx_rtcp() will be handled by get_frame().
-     */
-    if (stream->dir != PJMEDIA_DIR_DECODING) {
-	check_tx_rtcp(stream, pj_ntohl(channel->rtp.out_hdr.ts));
-    }
-
-    /* Do nothing if we have nothing to transmit */
-    if (frame_out.size == 0) {
-	if (stream->is_streaming) {
-	    PJ_LOG(5,(stream->port.info.name.ptr,"Starting silence"));
-	    stream->is_streaming = PJ_FALSE;
-	}
-
-	return PJ_SUCCESS;
-    }
-
-
-    /* Copy RTP header to the beginning of packet */
-    pj_memcpy(channel->out_pkt, rtphdr, sizeof(pjmedia_rtp_hdr));
-
-
-    /* Set RTP marker bit if currently not streaming */
-    if (stream->is_streaming == PJ_FALSE) {
-	pjmedia_rtp_hdr *rtp = channel->out_pkt;
-
-	rtp->m = 1;
-	PJ_LOG(5,(stream->port.info.name.ptr,"Start talksprut.."));
-    }
-
-    stream->is_streaming = PJ_TRUE;
-
-    /* Send the RTP packet to the transport. */
-    (*stream->transport->op->send_rtp)(stream->transport,
-				       channel->out_pkt, 
-				       frame_out.size + 
-					    sizeof(pjmedia_rtp_hdr));
-
-
-    /* Update stat */
-    pjmedia_rtcp_tx_rtp(&stream->rtcp, frame_out.size);
-
     /* If VAD is temporarily disabled during creation, enable it
      * after transmitting for VAD_SUSPEND_SEC seconds.
@@ -642,6 +724,49 @@
 
 
-    return PJ_SUCCESS;
-}
+    /* If encoder has different ptime than decoder, then the frame must
+     * be passed through the encoding buffer via rebuffer() function.
+     */
+    if (stream->enc_buf != NULL) {
+	pjmedia_frame tmp_rebuffer_frame;
+	pj_status_t status = PJ_SUCCESS;
+
+	/* Copy original frame to temporary frame since we need 
+	 * to modify it.
+	 */
+	pj_memcpy(&tmp_rebuffer_frame, frame, sizeof(pjmedia_frame));
+
+	/* Loop while we have full frame in enc_buffer */
+	for (;;) {
+	    pj_status_t st;
+
+	    /* Run rebuffer() */
+	    rebuffer(stream, &tmp_rebuffer_frame);
+
+	    /* Process this frame */
+	    st = put_frame_imp(port, &tmp_rebuffer_frame);
+	    if (st != PJ_SUCCESS)
+		status = st;
+
+	    /* If we still have full frame in the buffer, re-run
+	     * rebuffer() with NULL frame.
+	     */
+	    if (stream->enc_buf_count >= stream->enc_samples_per_frame) {
+
+		tmp_rebuffer_frame.type = PJMEDIA_FRAME_TYPE_NONE;
+
+	    } else {
+
+		/* Otherwise break */
+		break;
+	    }
+	}
+
+	return status;
+
+    } else {
+	return put_frame_imp(port, frame);
+    }
+}
+
 
 #if 0
@@ -1072,4 +1197,38 @@
 	goto err_cleanup;
 
+    /* If encoder and decoder's ptime are asymmetric, then we need to
+     * create buffer on the encoder side. This could happen for example
+     * with iLBC 
+     */
+    if (stream->codec_param.info.enc_ptime!=0 &&
+	stream->codec_param.info.enc_ptime!=stream->codec_param.info.frm_ptime)
+    {
+	unsigned ptime;
+
+	stream->enc_samples_per_frame = stream->codec_param.info.enc_ptime *
+					stream->port.info.clock_rate / 1000;
+
+	/* Set buffer size as twice the largest ptime value between
+	 * stream's ptime, encoder ptime, or decoder ptime.
+	 */
+
+	ptime = stream->port.info.samples_per_frame * 1000 /
+		stream->port.info.clock_rate;
+
+	if (stream->codec_param.info.enc_ptime > ptime)
+	    ptime = stream->codec_param.info.enc_ptime;
+
+	if (stream->codec_param.info.frm_ptime > ptime)
+	    ptime = stream->codec_param.info.frm_ptime;
+
+	ptime <<= 1;
+
+	/* Allocate buffer */
+	stream->enc_buf_size = stream->port.info.clock_rate * ptime / 1000;
+	stream->enc_buf = pj_pool_alloc(pool, stream->enc_buf_size * 2);
+
+    } else {
+	stream->enc_samples_per_frame = stream->port.info.samples_per_frame;
+    }
 
     /* Initially disable the VAD in the stream, to help traverse NAT better */
@@ -1084,6 +1243,7 @@
     /* Get the frame size: */
 
-    stream->frame_size = (stream->codec_param.info.avg_bps / 8) * 
+    stream->frame_size = ((stream->codec_param.info.avg_bps + 7) / 8) * 
 			  stream->codec_param.info.frm_ptime / 1000;
+
 
     /* Init RTCP session: */
