Index: pjproject/trunk/pjmedia/include/pjmedia/codec.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 866)
+++ pjproject/trunk/pjmedia/include/pjmedia/codec.h	(revision 867)
@@ -315,5 +315,5 @@
      */
     pj_status_t	(*open)(pjmedia_codec *codec, 
-			pjmedia_codec_param *param );
+			const pjmedia_codec_param *param );
 
     /** 
@@ -327,4 +327,20 @@
     pj_status_t (*close)(pjmedia_codec *codec);
 
+    /** 
+     * Modify the codec parameter after the codec is open. 
+     * Note that not all codec parameters can be modified during run-time. 
+     * When the parameter cannot be changed, this function will return 
+     * non-PJ_SUCCESS, and the original parameters will not be changed.
+     *
+     * Application can expect changing trivial codec settings such as
+     * changing VAD setting to succeed.
+     *
+     * @param codec	The codec instance.
+     * @param param	The new codec parameter.
+     *
+     * @return		PJ_SUCCESS on success.
+     */
+    pj_status_t	(*modify)(pjmedia_codec *codec, 
+			  const pjmedia_codec_param *param );
 
     /**
Index: pjproject/trunk/pjmedia/include/pjmedia/silencedet.h
===================================================================
--- pjproject/trunk/pjmedia/include/pjmedia/silencedet.h	(revision 866)
+++ pjproject/trunk/pjmedia/include/pjmedia/silencedet.h	(revision 867)
@@ -186,9 +186,4 @@
 
 
-/**
- * Declaration linear2ulaw
- */
-unsigned char linear2ulaw(int pcm_val);
-
 
 PJ_END_DECL
Index: pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia-codec/gsm.c	(revision 867)
@@ -55,6 +55,8 @@
 				    pj_pool_t *pool );
 static pj_status_t  gsm_codec_open( pjmedia_codec *codec, 
-				    pjmedia_codec_param *attr );
+				    const pjmedia_codec_param *attr );
 static pj_status_t  gsm_codec_close( pjmedia_codec *codec );
+static pj_status_t  gsm_codec_modify(pjmedia_codec *codec, 
+				     const pjmedia_codec_param *attr );
 static pj_status_t  gsm_codec_parse( pjmedia_codec *codec,
 				     void *pkt,
@@ -81,4 +83,5 @@
     &gsm_codec_open,
     &gsm_codec_close,
+    &gsm_codec_modify,
     &gsm_codec_parse,
     &gsm_codec_encode,
@@ -386,5 +389,5 @@
  */
 static pj_status_t gsm_codec_open( pjmedia_codec *codec, 
-				   pjmedia_codec_param *attr )
+				   const pjmedia_codec_param *attr )
 {
     struct gsm_data *gsm_data = codec->codec_data;
@@ -392,6 +395,4 @@
     pj_assert(gsm_data != NULL);
     pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL);
-
-    PJ_UNUSED_ARG(attr);
 
     gsm_data->encoder = gsm_create();
@@ -426,4 +427,22 @@
 	gsm_data->decoder = NULL;
     }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t  gsm_codec_modify(pjmedia_codec *codec, 
+				     const pjmedia_codec_param *attr )
+{
+    struct gsm_data *gsm_data = codec->codec_data;
+
+    pj_assert(gsm_data != NULL);
+    pj_assert(gsm_data->encoder == NULL && gsm_data->decoder == NULL);
+
+    gsm_data->vad_enabled = (attr->setting.vad != 0);
+    gsm_data->plc_enabled = (attr->setting.plc != 0);
 
     return PJ_SUCCESS;
Index: pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia-codec/ilbc.c	(revision 867)
@@ -64,6 +64,8 @@
 				    pj_pool_t *pool );
 static pj_status_t  ilbc_codec_open(pjmedia_codec *codec, 
-				    pjmedia_codec_param *attr );
+				    const pjmedia_codec_param *attr );
 static pj_status_t  ilbc_codec_close(pjmedia_codec *codec );
+static pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, 
+				      const pjmedia_codec_param *attr );
 static pj_status_t  ilbc_codec_parse(pjmedia_codec *codec,
 				     void *pkt,
@@ -90,4 +92,5 @@
     &ilbc_codec_open,
     &ilbc_codec_close,
+    &ilbc_codec_modify,
     &ilbc_codec_parse,
     &ilbc_codec_encode,
@@ -124,4 +127,5 @@
     char		 obj_name[PJ_MAX_OBJ_NAME];
     pjmedia_silence_det	*vad;
+    pj_bool_t		 vad_enabled;
     pj_bool_t		 plc_enabled;
 
@@ -361,11 +365,17 @@
  */
 static pj_status_t ilbc_codec_open(pjmedia_codec *codec, 
-				   pjmedia_codec_param *attr )
+				   const pjmedia_codec_param *param_attr )
 {
     struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
+    pjmedia_codec_param attr_copy, *attr;
+    pj_status_t status;
 
     pj_assert(ilbc_codec != NULL);
     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 */
@@ -405,15 +415,13 @@
 
     /* Save plc flags */
-    ilbc_codec->plc_enabled = attr->setting.plc != 0;
-
-    /* Create silence detector, if wanted. */
-    if (attr->setting.vad != 0) {
-	pj_status_t status;
-	status = pjmedia_silence_det_create(ilbc_codec->pool, CLOCK_RATE,
-					    ilbc_codec->enc_samples_per_frame,
-					    &ilbc_codec->vad);
-	if (status != PJ_SUCCESS)
-	    return status;
-    }
+    ilbc_codec->plc_enabled = (attr->setting.plc != 0);
+
+    /* Create silence detector. */
+    ilbc_codec->vad_enabled = (attr->setting.vad != 0);
+    status = pjmedia_silence_det_create(ilbc_codec->pool, CLOCK_RATE,
+					ilbc_codec->enc_samples_per_frame,
+					&ilbc_codec->vad);
+    if (status != PJ_SUCCESS)
+	return status;
 
     PJ_LOG(5,(ilbc_codec->obj_name, 
@@ -439,4 +447,17 @@
 }
 
+/*
+ * Modify codec settings.
+ */
+static pj_status_t  ilbc_codec_modify(pjmedia_codec *codec, 
+				      const pjmedia_codec_param *attr )
+{
+    struct ilbc_codec *ilbc_codec = (struct ilbc_codec*)codec;
+
+    ilbc_codec->plc_enabled = (attr->setting.plc != 0);
+    ilbc_codec->vad_enabled = (attr->setting.vad != 0);
+
+    return PJ_SUCCESS;
+}
 
 /*
@@ -494,5 +515,5 @@
 
     /* Detect silence */
-    if (ilbc_codec->vad) {
+    if (ilbc_codec->vad_enabled) {
 	pj_bool_t is_silence;
 
Index: pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia-codec/l16.c	(revision 867)
@@ -60,6 +60,8 @@
 			       pj_pool_t *pool );
 static pj_status_t  l16_open( pjmedia_codec *codec, 
-			       pjmedia_codec_param *attr );
+			       const pjmedia_codec_param *attr );
 static pj_status_t  l16_close( pjmedia_codec *codec );
+static pj_status_t  l16_modify(pjmedia_codec *codec, 
+			       const pjmedia_codec_param *attr );
 static pj_status_t  l16_parse(pjmedia_codec *codec,
 			      void *pkt,
@@ -83,4 +85,5 @@
     &l16_open,
     &l16_close,
+    &l16_modify,
     &l16_parse,
     &l16_encode,
@@ -487,5 +490,5 @@
 
 static pj_status_t l16_open(pjmedia_codec *codec, 
-			    pjmedia_codec_param *attr )
+			    const pjmedia_codec_param *attr )
 {
     /* Nothing to do.. */
@@ -500,4 +503,13 @@
     /* Nothing to do */
     return PJ_SUCCESS;
+}
+
+static pj_status_t  l16_modify(pjmedia_codec *codec, 
+			       const pjmedia_codec_param *attr )
+{
+    /* Don't want to do anything. */
+    PJ_UNUSED_ARG(codec);
+    PJ_UNUSED_ARG(attr);
+    return PJ_EINVALIDOP;
 }
 
Index: pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia-codec/speex_codec.c	(revision 867)
@@ -60,6 +60,8 @@
 				    pj_pool_t *pool );
 static pj_status_t  spx_codec_open( pjmedia_codec *codec, 
-				    pjmedia_codec_param *attr );
+				    const pjmedia_codec_param *attr );
 static pj_status_t  spx_codec_close( pjmedia_codec *codec );
+static pj_status_t  spx_codec_modify(pjmedia_codec *codec, 
+				     const pjmedia_codec_param *attr );
 static pj_status_t  spx_codec_parse( pjmedia_codec *codec,
 				     void *pkt,
@@ -86,4 +88,5 @@
     &spx_codec_open,
     &spx_codec_close,
+    &spx_codec_modify,
     &spx_codec_parse,
     &spx_codec_encode,
@@ -545,5 +548,5 @@
  */
 static pj_status_t spx_codec_open( pjmedia_codec *codec, 
-				   pjmedia_codec_param *attr )
+				   const pjmedia_codec_param *attr )
 {
     struct spx_private *spx;
@@ -552,4 +555,7 @@
     spx = (struct spx_private*) codec->codec_data;
     id = spx->param_id;
+
+    /* Only supports one frame per packet */
+    PJ_ASSERT_RETURN(attr->setting.frm_per_pkt==1, PJ_EINVAL);
 
     /* 
@@ -626,4 +632,31 @@
 	speex_bits_destroy( &spx->dec_bits );
     }
+
+    return PJ_SUCCESS;
+}
+
+
+/*
+ * Modify codec settings.
+ */
+static pj_status_t  spx_codec_modify(pjmedia_codec *codec, 
+				     const pjmedia_codec_param *attr )
+{
+    struct spx_private *spx;
+    int tmp;
+
+    spx = (struct spx_private*) codec->codec_data;
+
+    /* Only supports one frame per packet */
+    PJ_ASSERT_RETURN(attr->setting.frm_per_pkt==1, PJ_EINVAL);
+
+    /* VAD */
+    tmp = (attr->setting.vad != 0);
+    speex_encoder_ctl(spx->enc, SPEEX_SET_VAD, &tmp);
+    speex_encoder_ctl(spx->enc, SPEEX_SET_DTX, &tmp);
+
+    /* PENH */
+    tmp = attr->setting.penh;
+    speex_decoder_ctl(spx->dec, SPEEX_SET_ENH, &tmp);
 
     return PJ_SUCCESS;
Index: pjproject/trunk/pjmedia/src/pjmedia/echo_suppress.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/echo_suppress.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia/echo_suppress.c	(revision 867)
@@ -84,4 +84,5 @@
     PJ_UNUSED_ARG(clock_rate);
     PJ_UNUSED_ARG(options);
+    PJ_UNUSED_ARG(latency_ms);
 
     ec = pj_pool_zalloc(pool, sizeof(struct echo_supp));
Index: pjproject/trunk/pjmedia/src/pjmedia/g711.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/g711.c	(revision 866)
+++ pjproject/trunk/pjmedia/src/pjmedia/g711.c	(revision 867)
@@ -63,6 +63,8 @@
 			       pj_pool_t *pool );
 static pj_status_t  g711_open( pjmedia_codec *codec, 
-			       pjmedia_codec_param *attr );
+			       const pjmedia_codec_param *attr );
 static pj_status_t  g711_close( pjmedia_codec *codec );
+static pj_status_t  g711_modify(pjmedia_codec *codec, 
+			        const pjmedia_codec_param *attr );
 static pj_status_t  g711_parse(pjmedia_codec *codec,
 			       void *pkt,
@@ -89,4 +91,5 @@
     &g711_open,
     &g711_close,
+    &g711_modify,
     &g711_parse,
     &g711_encode,
@@ -395,5 +398,5 @@
 
 static pj_status_t g711_open(pjmedia_codec *codec, 
-			     pjmedia_codec_param *attr )
+			     const pjmedia_codec_param *attr )
 {
     struct g711_private *priv = codec->codec_data;
@@ -408,4 +411,18 @@
     PJ_UNUSED_ARG(codec);
     /* Nothing to do */
+    return PJ_SUCCESS;
+}
+
+static pj_status_t  g711_modify(pjmedia_codec *codec, 
+			        const pjmedia_codec_param *attr )
+{
+    struct g711_private *priv = codec->codec_data;
+
+    if (attr->info.pt != priv->pt)
+	return PJMEDIA_EINVALIDPT;
+
+    priv->plc_enabled = (attr->setting.plc != 0);
+    priv->vad_enabled = (attr->setting.vad != 0);
+
     return PJ_SUCCESS;
 }
