Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5675)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5676)
@@ -488,4 +488,40 @@
 
 
+/**
+ * Structure to be passed to on stream created callback.
+ * See #on_stream_created2().
+ */
+typedef struct pjsua_on_stream_created_param
+{
+    /**
+     * The media stream, read-only.
+     */
+    pjmedia_stream 	*stream;
+
+    /**
+     * Stream index in the media session, read-only.
+     */
+    unsigned 		 stream_idx;
+
+    /**
+     * Specify if PJSUA should take ownership of the port returned in
+     * the port parameter below. If set to PJ_TRUE,
+     * pjmedia_port_destroy() will be called on the port when it is
+     * no longer needed.
+     *
+     * Default: PJ_FALSE
+     */
+    pj_bool_t 		 destroy_port;
+
+    /**
+     * On input, it specifies the media port of the stream. Application
+     * may modify this pointer to point to different media port to be
+     * registered to the conference bridge.
+     */
+    pjmedia_port        *port;
+
+} pjsua_on_stream_created_param;
+
+
 /** 
  * Enumeration of media transport state types.
@@ -822,4 +858,7 @@
      * media port then will be added to the conference bridge instead.
      *
+     * Note: if implemented, #on_stream_created2() callback will be called
+     * instead of this one. 
+     *
      * @param call_id	    Call identification.
      * @param strm	    Media stream.
@@ -834,4 +873,16 @@
                               unsigned stream_idx,
 			      pjmedia_port **p_port);
+
+    /**
+     * Notify application when media session is created and before it is
+     * registered to the conference bridge. Application may return different
+     * media port if it has added media processing port to the stream. This
+     * media port then will be added to the conference bridge instead.
+     *
+     * @param call_id	    Call identification.
+     * @param param	    The on stream created callback parameter.
+     */
+    void (*on_stream_created2)(pjsua_call_id call_id,
+			       pjsua_on_stream_created_param *param);
 
     /**
Index: /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5675)
+++ /pjproject/trunk/pjsip/include/pjsua-lib/pjsua_internal.h	(revision 5676)
@@ -52,4 +52,6 @@
 	struct {
 	    pjmedia_stream *stream;    /**< The audio stream.		    */
+	    pjmedia_port   *media_port;/**< The media port.                 */
+	    pj_bool_t	    destroy_port;/**< Destroy the media port?	    */
 	    int		    conf_slot; /**< Slot # in conference bridge.    */
 	} a;
Index: /pjproject/trunk/pjsip/include/pjsua2/call.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5675)
+++ /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5676)
@@ -692,13 +692,23 @@
 {
     /**
-     * Media stream.
+     * Media stream, read-only.
      */
     MediaStream stream;
     
     /**
-     * Stream index in the media session.
+     * Stream index in the media session, read-only.
      */
     unsigned    streamIdx;
     
+    /**
+     * Specify if PJSUA2 should take ownership of the port returned in
+     * the pPort parameter below. If set to PJ_TRUE,
+     * pjmedia_port_destroy() will be called on the port when it is
+     * no longer needed.
+     *
+     * Default: PJ_FALSE
+     */
+    bool 	destroyPort;
+
     /**
      * On input, it specifies the media port of the stream. Application
Index: /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5675)
+++ /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5676)
@@ -1665,8 +1665,6 @@
                                     pj_pool_t *pool,
                                     const pjmedia_sdp_session *rem_sdp);
-    static void on_stream_created(pjsua_call_id call_id,
-                                  pjmedia_stream *strm,
-                                  unsigned stream_idx,
-                                  pjmedia_port **p_port);
+    static void on_stream_created2(pjsua_call_id call_id,
+				   pjsua_on_stream_created_param *param);
     static void on_stream_destroyed(pjsua_call_id call_id,
                                     pjmedia_stream *strm,
Index: /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c	(revision 5675)
+++ /pjproject/trunk/pjsip/src/pjsua-lib/pjsua_aud.c	(revision 5676)
@@ -532,4 +532,10 @@
 	}
 
+	if (call_med->strm.a.media_port) {
+	    if (call_med->strm.a.destroy_port)
+		pjmedia_port_destroy(call_med->strm.a.media_port);
+	    call_med->strm.a.media_port = NULL;
+	}
+
 	pjmedia_stream_destroy(strm);
 	call_med->strm.a.stream = NULL;
@@ -576,5 +582,4 @@
 {
     pjsua_call *call = call_med->call;
-    pjmedia_port *media_port;
     unsigned strm_idx = call_med->idx;
     pj_status_t status = PJ_SUCCESS;
@@ -646,5 +651,6 @@
 	 * We need the port interface to add to the conference bridge.
 	 */
-	pjmedia_stream_get_port(call_med->strm.a.stream, &media_port);
+	pjmedia_stream_get_port(call_med->strm.a.stream,
+				&call_med->strm.a.media_port);
 
 	/* Notify application about stream creation.
@@ -652,8 +658,21 @@
 	 * media port
 	 */
-	if (pjsua_var.ua_cfg.cb.on_stream_created) {
-	    pjsua_var.ua_cfg.cb.on_stream_created(call->index,
+	if (pjsua_var.ua_cfg.cb.on_stream_created2) {
+	    pjsua_on_stream_created_param prm;
+	    
+	    prm.stream = call_med->strm.a.stream;
+	    prm.stream_idx = strm_idx;
+	    prm.destroy_port = PJ_FALSE;
+	    prm.port = call_med->strm.a.media_port;
+	    (*pjsua_var.ua_cfg.cb.on_stream_created2)(call->index, &prm);
+	    
+	    call_med->strm.a.destroy_port = prm.destroy_port;
+	    call_med->strm.a.media_port = prm.port;
+
+	} else if (pjsua_var.ua_cfg.cb.on_stream_created) {
+	    (*pjsua_var.ua_cfg.cb.on_stream_created)(call->index,
 						  call_med->strm.a.stream,
-						  strm_idx, &media_port);
+						  strm_idx,
+						  &call_med->strm.a.media_port);
 	}
 
@@ -672,10 +691,10 @@
 		port_name = pj_str("call");
 	    }
-	    status = pjmedia_conf_add_port( pjsua_var.mconf,
-					    call->inv->pool,
-					    media_port,
-					    &port_name,
-					    (unsigned*)
-					    &call_med->strm.a.conf_slot);
+	    status = pjmedia_conf_add_port(pjsua_var.mconf,
+					   call->inv->pool,
+					   call_med->strm.a.media_port,
+					   &port_name,
+					   (unsigned*)
+					   &call_med->strm.a.conf_slot);
 	    if (status != PJ_SUCCESS) {
 		goto on_return;
Index: /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5675)
+++ /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5676)
@@ -1071,8 +1071,6 @@
 }
 
-void Endpoint::on_stream_created(pjsua_call_id call_id,
-                                 pjmedia_stream *strm,
-                                 unsigned stream_idx,
-                                 pjmedia_port **p_port)
+void Endpoint::on_stream_created2(pjsua_call_id call_id,
+				  pjsua_on_stream_created_param *param)
 {
     Call *call = Call::lookup(call_id);
@@ -1082,12 +1080,13 @@
     
     OnStreamCreatedParam prm;
-    prm.stream = strm;
-    prm.streamIdx = stream_idx;
-    prm.pPort = (void *)*p_port;
+    prm.stream = param->stream;
+    prm.streamIdx = param->stream_idx;
+    prm.destroyPort = param->destroy_port;
+    prm.pPort = (MediaPort)param->port;
     
     call->onStreamCreated(prm);
     
-    if (prm.pPort != (void *)*p_port)
-        *p_port = (pjmedia_port *)prm.pPort;
+    param->destroy_port = prm.destroyPort;
+    param->port = (pjmedia_port *)prm.pPort;
 }
 
@@ -1558,5 +1557,5 @@
     ua_cfg.cb.on_call_media_state       = &Endpoint::on_call_media_state;
     ua_cfg.cb.on_call_sdp_created       = &Endpoint::on_call_sdp_created;
-    ua_cfg.cb.on_stream_created         = &Endpoint::on_stream_created;
+    ua_cfg.cb.on_stream_created2        = &Endpoint::on_stream_created2;
     ua_cfg.cb.on_stream_destroyed       = &Endpoint::on_stream_destroyed;
     ua_cfg.cb.on_dtmf_digit             = &Endpoint::on_dtmf_digit;
