Index: pjproject/branches/projects/jbuf2/pjmedia/src/pjmedia/stream.c
===================================================================
--- pjproject/branches/projects/jbuf2/pjmedia/src/pjmedia/stream.c	(revision 1778)
+++ pjproject/branches/projects/jbuf2/pjmedia/src/pjmedia/stream.c	(revision 1779)
@@ -21,5 +21,5 @@
 #include <pjmedia/rtp.h>
 #include <pjmedia/rtcp.h>
-#include <pjmedia/jbuf.h>
+#include <pjmedia/jbuf2.h>
 #include <pj/array.h>
 #include <pj/assert.h>
@@ -109,6 +109,5 @@
 
     pj_mutex_t		    *jb_mutex;
-    pjmedia_jbuf	    *jb;	    /**< Jitter buffer.		    */
-    char		     jb_last_frm;   /**< Last frame type from jb    */
+    pjmedia_jb2_t	    *jb;	    /**< Jitter buffer.		    */
 
     pjmedia_rtcp_session     rtcp;	    /**< RTCP for incoming RTP.	    */
@@ -153,4 +152,87 @@
 }
 
+static pj_status_t jb_decode(pjmedia_jb2_frame *frame, void *userdata)
+{
+    pjmedia_stream *stream = (pjmedia_stream*) userdata;
+    pj_status_t status = PJ_SUCCESS;
+    pjmedia_frame frame_in, frame_out;
+
+    pj_assert(frame && userdata);
+
+    /* Decode */
+    frame_in.buf = stream->dec->out_pkt;
+    frame_in.size = frame->size;
+    frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;
+    pj_memcpy(frame_in.buf, frame->buffer, frame->size);
+
+    frame_out.buf = frame->buffer;
+    frame_out.size = (stream->codec_param.info.clock_rate *
+		     stream->codec_param.info.frm_ptime / 1000)*
+		     (stream->codec_param.info.pcm_bits_per_sample/8);
+
+    status = stream->codec->op->decode( stream->codec, &frame_in,
+					frame_out.size, &frame_out);
+
+    /* NOTE: frame_out.size is not valid for speex/16000 */
+    frame->size = frame_out.size;
+    if (status != PJ_SUCCESS) {
+	LOGERR_((stream->port.info.name.ptr, "codec decode() error", 
+		 status));
+
+	pj_bzero(frame->buffer, frame->size);
+    }
+
+    return status;
+}
+
+static pj_status_t jb_plc(pjmedia_jb2_frame *frame, void *userdata)
+{
+    pjmedia_stream *stream = (pjmedia_stream*) userdata;
+    pj_status_t status = PJ_SUCCESS;
+
+    pj_assert(frame && stream);
+
+    /* Activate PLC */
+    if (stream->codec->op->recover && 
+	stream->codec_param.setting.plc) 
+    {
+	pjmedia_frame frame_out;
+
+	frame_out.buf = frame->buffer;
+	frame_out.size = frame->size;
+	status = (*stream->codec->op->recover)(stream->codec,
+					       frame_out.size,
+					       &frame_out);
+    } else {
+	status = PJ_EINVAL;
+    }
+
+    if (status != PJ_SUCCESS) {
+	/* Either PLC failed or PLC not supported/enabled */
+	pj_bzero(frame->buffer, frame->size);
+	PJ_LOG(5,(stream->port.info.name.ptr,  "Frame lost!"));
+
+    } else {
+	PJ_LOG(5,(stream->port.info.name.ptr, 
+		  "Lost frame recovered"));
+    }
+
+    return status;
+}
+
+static pj_status_t jb_cng(pjmedia_jb2_frame *frame, void *userdata)
+{
+    pjmedia_stream *stream = (pjmedia_stream*) userdata;
+
+    pj_assert(frame && stream);
+
+    frame->size = (stream->codec_param.info.clock_rate *
+		   stream->codec_param.info.frm_ptime / 1000)*
+		  (stream->codec_param.info.pcm_bits_per_sample/8);
+    pj_bzero(frame->buffer, frame->size);
+
+    return PJ_SUCCESS;
+}
+
 
 /*
@@ -160,4 +242,5 @@
  * needs to feed the player with some frames.
  */
+
 static pj_status_t get_frame( pjmedia_port *port, pjmedia_frame *frame)
 {
@@ -167,5 +250,5 @@
     pj_int16_t *p_out_samp;
     pj_status_t status;
-
+    pjmedia_jb2_frame jb_frame;
 
     /* Return no frame is channel is paused */
@@ -192,155 +275,8 @@
 	 samples_count += samples_per_frame) 
     {
-	char frame_type;
-
 	/* Get frame from jitter buffer. */
-	pjmedia_jbuf_get_frame(stream->jb, channel->out_pkt, &frame_type);
-	
-	if (frame_type == PJMEDIA_JB_MISSING_FRAME) {
-	    
-	    /* Activate PLC */
-	    if (stream->codec->op->recover && 
-		stream->codec_param.setting.plc) 
-	    {
-		pjmedia_frame frame_out;
-
-		frame_out.buf = p_out_samp + samples_count;
-		frame_out.size = frame->size - samples_count*2;
-		status = (*stream->codec->op->recover)(stream->codec,
-						       frame_out.size,
-						       &frame_out);
-
-	    } else {
-		status = -1;
-	    }
-
-	    if (status != PJ_SUCCESS) {
-		/* Either PLC failed or PLC not supported/enabled */
-		pjmedia_zero_samples(p_out_samp + samples_count,
-				     samples_required - samples_count);
-		PJ_LOG(5,(stream->port.info.name.ptr,  "Frame lost!"));
-
-	    } else {
-		PJ_LOG(5,(stream->port.info.name.ptr, 
-			  "Lost frame recovered"));
-	    }
-	    
-	} else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
-
-	    /* Jitter buffer is empty. If this is the first "empty" state,
-	     * activate PLC to smoothen the fade-out, otherwise zero
-	     * the frame. 
-	     */
-	    if (frame_type != stream->jb_last_frm) {
-		pjmedia_jb_state jb_state;
-
-		/* Activate PLC to smoothen the missing frame */
-		if (stream->codec->op->recover && 
-		    stream->codec_param.setting.plc) 
-		{
-		    pjmedia_frame frame_out;
-
-		    do {
-			frame_out.buf = p_out_samp + samples_count;
-			frame_out.size = frame->size - samples_count*2;
-			status = (*stream->codec->op->recover)(stream->codec,
-							       frame_out.size,
-							       &frame_out);
-			if (status != PJ_SUCCESS)
-			    break;
-			samples_count += samples_per_frame;
-
-		    } while (samples_count < samples_required);
-
-		} 
-
-		/* Report the state of jitter buffer */
-		pjmedia_jbuf_get_state(stream->jb, &jb_state);
-		PJ_LOG(5,(stream->port.info.name.ptr, 
-			  "Jitter buffer empty (prefetch=%d)", 
-			  jb_state.prefetch));
-
-	    }
-
-	    if (samples_count < samples_required) {
-		pjmedia_zero_samples(p_out_samp + samples_count,
-				     samples_required - samples_count);
-		samples_count = samples_required;
-	    }
-
-	    stream->jb_last_frm = frame_type;
-	    break;
-
-	} else if (frame_type != PJMEDIA_JB_NORMAL_FRAME) {
-
-	    pjmedia_jb_state jb_state;
-
-	    /* It can only be PJMEDIA_JB_ZERO_PREFETCH frame */
-	    pj_assert(frame_type == PJMEDIA_JB_ZERO_PREFETCH_FRAME);
-
-	    /* Get the state of jitter buffer */
-	    pjmedia_jbuf_get_state(stream->jb, &jb_state);
-
-	    /* Always activate PLC when it's available.. */
-	    if (stream->codec->op->recover && 
-		stream->codec_param.setting.plc) 
-	    {
-		pjmedia_frame frame_out;
-
-		do {
-		    frame_out.buf = p_out_samp + samples_count;
-		    frame_out.size = frame->size - samples_count*2;
-		    status = (*stream->codec->op->recover)(stream->codec,
-							   frame_out.size,
-							   &frame_out);
-		    if (status != PJ_SUCCESS)
-			break;
-		    samples_count += samples_per_frame;
-
-		} while (samples_count < samples_required);
-
-		if (stream->jb_last_frm != frame_type) {
-		    PJ_LOG(5,(stream->port.info.name.ptr, 
-			      "Jitter buffer is bufferring with plc (prefetch=%d)",
-			      jb_state.prefetch));
-		}
-
-	    } 
-
-	    if (samples_count < samples_required) {
-		pjmedia_zero_samples(p_out_samp + samples_count,
-				     samples_required - samples_count);
-		samples_count = samples_required;
-		PJ_LOG(5,(stream->port.info.name.ptr, 
-			  "Jitter buffer is bufferring (prefetch=%d)..", 
-			  jb_state.prefetch));
-	    }
-
-	    stream->jb_last_frm = frame_type;
-	    break;
-
-	} else {
-	    /* Got "NORMAL" frame from jitter buffer */
-	    pjmedia_frame frame_in, frame_out;
-
-	    /* Decode */
-	    frame_in.buf = channel->out_pkt;
-	    frame_in.size = stream->frame_size;
-	    frame_in.type = PJMEDIA_FRAME_TYPE_AUDIO;  /* ignored */
-
-	    frame_out.buf = p_out_samp + samples_count;
-	    frame_out.size = frame->size - samples_count*BYTES_PER_SAMPLE;
-	    status = stream->codec->op->decode( stream->codec, &frame_in,
-						frame_out.size, &frame_out);
-	    if (status != 0) {
-		LOGERR_((port->info.name.ptr, "codec decode() error", 
-			 status));
-
-		pjmedia_zero_samples(p_out_samp + samples_count, 
-				     samples_per_frame);
-	    }
-	}
-
-	stream->jb_last_frm = frame_type;
+	jb_frame.buffer = p_out_samp + samples_count;
+	jb_frame.size = frame->size - samples_count*2;
+	status = pjmedia_jb2_get_frame(stream->jb, &jb_frame);
     }
 
@@ -1000,5 +936,5 @@
     pj_mutex_lock( stream->jb_mutex );
     if (seq_st.status.flag.restart) {
-	status = pjmedia_jbuf_reset(stream->jb);
+	status = pjmedia_jb2_reset(stream->jb);
 	PJ_LOG(4,(stream->port.info.name.ptr, "Jitter buffer reset"));
 
@@ -1014,4 +950,5 @@
 	unsigned samples_per_frame;
 	pjmedia_frame frames[MAX];
+	pjmedia_jb2_frame jb_frame;
 
 	/* Get the timestamp of the first sample */
@@ -1039,15 +976,20 @@
 			    
 	for (i=0; i<count; ++i) {
-	    unsigned ext_seq;
-
-	    ext_seq = (unsigned)(frames[i].timestamp.u64 /
-				 samples_per_frame);
-	    pjmedia_jbuf_put_frame(stream->jb, frames[i].buf, 
-				   frames[i].size, ext_seq);
-
+	    jb_frame.buffer = frames[i].buf;
+	    jb_frame.pt = (pj_uint8_t)hdr->pt;
+	    jb_frame.seq = ntohs(hdr->seq);
+	    jb_frame.size = frames[i].size;
+	    jb_frame.ts = ntohl(hdr->ts) + samples_per_frame*i;
+	    jb_frame.type = PJMEDIA_JB_FT_NORMAL_FRAME;
+	    
+	    status = pjmedia_jb2_put_frame(stream->jb, &jb_frame);
+	    if (status != PJ_SUCCESS) {
+		LOGERR_((stream->port.info.name.ptr, "Jitter buffer put() error", 
+			status));
+	    }
 	}
     }
+
     pj_mutex_unlock( stream->jb_mutex );
-
 
     /* Check if now is the time to transmit RTCP SR/RR report.
@@ -1057,10 +999,4 @@
     if (stream->dir == PJMEDIA_DIR_DECODING) {
 	check_tx_rtcp(stream, pj_ntohl(hdr->ts));
-    }
-
-    if (status != 0) {
-	LOGERR_((stream->port.info.name.ptr, "Jitter buffer put() error", 
-		status));
-	return;
     }
 }
@@ -1161,6 +1097,7 @@
     pjmedia_stream *stream;
     pj_str_t name;
-    unsigned jb_init, jb_max, jb_min_pre, jb_max_pre;
     pj_status_t status;
+    pjmedia_jb2_setting jb_setting;
+    pjmedia_jb2_cb jb_cb;
 
     PJ_ASSERT_RETURN(pool && info && p_stream, PJ_EINVAL);
@@ -1316,36 +1253,25 @@
 
     /* Init jitter buffer parameters: */
-    if (info->jb_max > 0)
-	jb_max = info->jb_max;
-    else
-	jb_max = 360 / stream->codec_param.info.frm_ptime;
-
-    if (info->jb_min_pre >= 0)
-	jb_min_pre = info->jb_min_pre;
-    else
-	jb_min_pre = 60 / stream->codec_param.info.frm_ptime;
-
-    if (info->jb_max_pre > 0)
-	jb_max_pre = info->jb_max_pre;
-    else
-	jb_max_pre = 240 / stream->codec_param.info.frm_ptime;
-
-    if (info->jb_init >= 0)
-	jb_init = info->jb_init;
-    else
-	jb_init = (jb_min_pre + jb_max_pre) / 2;
-
+    pj_bzero(&jb_setting, sizeof(jb_setting));
+    jb_setting.samples_per_frame = info->fmt.clock_rate * 
+				   stream->codec_param.info.frm_ptime /
+				   1000;
+    jb_setting.frame_size = jb_setting.samples_per_frame * 
+			    stream->codec_param.info.pcm_bits_per_sample / 8;
+    jb_setting.max_frames = 0;
+
+    pj_bzero(&jb_cb, sizeof(jb_cb));
+    jb_cb.decode = &jb_decode;
+    jb_cb.plc = &jb_plc;
+    jb_cb.cng = NULL; //&jb_cng;
+    jb_cb.user_data = stream;
 
     /* Create jitter buffer */
-    status = pjmedia_jbuf_create(pool, &stream->port.info.name,
-				 stream->frame_size, 
-				 stream->codec_param.info.frm_ptime,
-				 jb_max, &stream->jb);
+    status = pjmedia_jb2_create(pool, &stream->port.info.name, &jb_setting, 
+				&jb_cb, &stream->jb);
+
     if (status != PJ_SUCCESS)
 	goto err_cleanup;
 
-
-    /* Set up jitter buffer */
-    pjmedia_jbuf_set_adaptive( stream->jb, jb_init, jb_min_pre, jb_max_pre);
 
     /* Create decoder channel: */
@@ -1417,4 +1343,10 @@
     }
 
+    /* Destroy JB */
+    if (stream->jb) {
+	pjmedia_jb2_destroy(stream->jb);
+	stream->jb = NULL;
+    }
+
     /* Free mutex */
     
@@ -1508,5 +1440,5 @@
 	/* Also reset jitter buffer */
 	pj_mutex_lock( stream->jb_mutex );
-	pjmedia_jbuf_reset(stream->jb);
+	pjmedia_jb2_reset(stream->jb);
 	pj_mutex_unlock( stream->jb_mutex );
 
