Index: pjproject/trunk/pjmedia/src/pjmedia/stream.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 2844)
+++ pjproject/trunk/pjmedia/src/pjmedia/stream.c	(revision 2850)
@@ -44,4 +44,11 @@
 #define BYTES_PER_SAMPLE		2
 
+/* Limit the number of synthetic audio samples that are generated by PLC.
+ * Normally PLC should have it's own means to limit the number of
+ * synthetic frames, so we need to set this to a reasonably large value
+ * just as precaution
+ */
+#define MAX_PLC_MSEC			240
+
 /**
  * Media channel.
@@ -99,4 +106,7 @@
     unsigned		     enc_buf_count; /**< Number of samples in the
 						 encoding buffer.	    */
+
+    unsigned		     plc_cnt;	    /**< # of consecutive PLC frames*/
+    unsigned		     max_plc_cnt;   /**< Max # of PLC frames	    */
 
     unsigned		     vad_enabled;   /**< VAD enabled in param.	    */
@@ -198,11 +208,11 @@
 }
 
+#if defined(PJMEDIA_STREAM_ENABLE_KA) && PJMEDIA_STREAM_ENABLE_KA != 0
 /*
- * Send keep-alive packet.
+ * Send keep-alive packet using non-codec frame.
  */
 static void send_keep_alive_packet(pjmedia_stream *stream)
 {
-#if defined(PJMEDIA_STREAM_ENABLE_KA) && \
-    PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP
+#if PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_EMPTY_RTP
 
     /* Keep-alive packet is empty RTP */
@@ -225,6 +235,5 @@
     TRC_((stream->port.info.name.ptr, "Keep-alive sent (empty RTP)"));
 
-#elif defined(PJMEDIA_STREAM_ENABLE_KA) && \
-      PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
+#elif PJMEDIA_STREAM_ENABLE_KA == PJMEDIA_STREAM_KA_USER
 
     /* Keep-alive packet is defined in PJMEDIA_STREAM_KA_USER_PKT */
@@ -244,4 +253,5 @@
 #endif
 }
+#endif	/* defined(PJMEDIA_STREAM_ENABLE_KA) */
 
 /*
@@ -295,5 +305,6 @@
 	    /* Activate PLC */
 	    if (stream->codec->op->recover && 
-		stream->codec_param.setting.plc) 
+		stream->codec_param.setting.plc &&
+		stream->plc_cnt < stream->max_plc_cnt) 
 	    {
 		pjmedia_frame frame_out;
@@ -305,4 +316,6 @@
 						       &frame_out);
 
+		++stream->plc_cnt;
+
 	    } else {
 		status = -1;
@@ -319,5 +332,5 @@
 			  "Lost frame recovered"));
 	    }
-	    
+
 	} else if (frame_type == PJMEDIA_JB_ZERO_EMPTY_FRAME) {
 
@@ -326,5 +339,8 @@
 	     * the frame. 
 	     */
-	    if (frame_type != stream->jb_last_frm) {
+	    //Using this "if" will only invoke PLC for the first packet
+	    //lost and not the subsequent ones.
+	    //if (frame_type != stream->jb_last_frm) {
+	    if (1) {
 		pjmedia_jb_state jb_state;
 		const char *with_plc = "";
@@ -332,5 +348,6 @@
 		/* Activate PLC to smoothen the missing frame */
 		if (stream->codec->op->recover && 
-		    stream->codec_param.setting.plc) 
+		    stream->codec_param.setting.plc &&
+		    stream->plc_cnt < stream->max_plc_cnt) 
 		{
 		    pjmedia_frame frame_out;
@@ -344,7 +361,10 @@
 			if (status != PJ_SUCCESS)
 			    break;
+
 			samples_count += samples_per_frame;
-
-		    } while (samples_count < samples_required);
+			++stream->plc_cnt;
+
+		    } while (samples_count < samples_required &&
+			     stream->plc_cnt < stream->max_plc_cnt);
 
 		    with_plc = ", plc invoked";
@@ -380,5 +400,6 @@
 	    /* Always activate PLC when it's available.. */
 	    if (stream->codec->op->recover && 
-		stream->codec_param.setting.plc) 
+		stream->codec_param.setting.plc &&
+		stream->plc_cnt < stream->max_plc_cnt) 
 	    {
 		pjmedia_frame frame_out;
@@ -394,7 +415,11 @@
 		    samples_count += samples_per_frame;
 
-		} while (samples_count < samples_required);
-
-		if (stream->jb_last_frm != frame_type) {
+		    ++stream->plc_cnt;
+
+		} while (samples_count < samples_required &&
+			 stream->plc_cnt < stream->max_plc_cnt);
+
+		//if (stream->jb_last_frm != frame_type) {
+		if (1) {
 		    PJ_LOG(5,(stream->port.info.name.ptr, 
 			      "Jitter buffer is bufferring with plc (prefetch=%d)",
@@ -419,4 +444,6 @@
 	    /* Got "NORMAL" frame from jitter buffer */
 	    pjmedia_frame frame_in, frame_out;
+
+	    stream->plc_cnt = 0;
 
 	    /* Decode */
@@ -1822,4 +1849,8 @@
 	++stream->frame_size;
     }
+
+    /* How many consecutive PLC frames can be generated */
+    stream->max_plc_cnt = (MAX_PLC_MSEC+stream->codec_param.info.frm_ptime-1)/
+			    stream->codec_param.info.frm_ptime;
 
 #if defined(PJMEDIA_HANDLE_G722_MPEG_BUG) && (PJMEDIA_HANDLE_G722_MPEG_BUG!=0)
