Index: pjproject/branches/1.x/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/branches/1.x/pjsip/include/pjsua-lib/pjsua.h	(revision 3584)
+++ pjproject/branches/1.x/pjsip/include/pjsua-lib/pjsua.h	(revision 3585)
@@ -419,4 +419,20 @@
 						 registration callback.	*/
 } pjsua_reg_info;
+
+
+/**
+ * This enumeration specifies the options for custom media transport creation.
+ */
+typedef enum pjsua_create_media_transport_flag
+{
+   /**
+    * This flag indicates that the media transport must also close its
+    * "member" or "child" transport when pjmedia_transport_close() is
+    * called. If this flag is not specified, then the media transport
+    * must not call pjmedia_transport_close() of its member transport.
+    */
+   PJSUA_MED_TP_CLOSE_MEMBER = 1
+
+} pjsua_create_media_transport_flag;
 
 
@@ -919,4 +935,30 @@
 				   pj_status_t status, void *param);
 
+    /**
+     * This callback can be used by application to implement custom media
+     * transport adapter for the call, or to replace the media transport
+     * with something completely new altogether.
+     *
+     * This callback is called when a new call is created. The library has
+     * created a media transport for the call, and it is provided as the
+     * \a base_tp argument of this callback. Upon returning, the callback
+     * must return an instance of media transport to be used by the call.
+     *
+     * @param call_id       Call ID
+     * @param media_idx     The media index in the SDP for which this media
+     *                      transport will be used.
+     * @param base_tp       The media transport which otherwise will be
+     *                      used by the call has this callback not been
+     *                      implemented.
+     * @param flags         Bitmask from pjsua_create_media_transport_flag.
+     *
+     * @return              The callback must return an instance of media
+     *                      transport to be used by the call.
+     */
+    pjmedia_transport* (*on_create_media_transport)(pjsua_call_id call_id,
+                                                    unsigned media_idx,
+                                                    pjmedia_transport *base_tp,
+                                                    unsigned flags);
+
 } pjsua_callback;
 
Index: pjproject/branches/1.x/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- pjproject/branches/1.x/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3584)
+++ pjproject/branches/1.x/pjsip/src/pjsua-lib/pjsua_media.c	(revision 3585)
@@ -1175,4 +1175,6 @@
     pjsua_call *call = &pjsua_var.calls[call_id];
     pj_status_t status;
+    pj_bool_t use_custom_med_tp = PJ_FALSE;
+    unsigned custom_med_tp_flags = 0;
 
 #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
@@ -1193,9 +1195,15 @@
     }
 
+    if (!call->med_orig &&
+        pjsua_var.ua_cfg.cb.on_create_media_transport)
+    {
+        use_custom_med_tp = PJ_TRUE;
+    }
+
 #if defined(PJMEDIA_HAS_SRTP) && (PJMEDIA_HAS_SRTP != 0)
     /* This function may be called when SRTP transport already exists 
      * (e.g: in re-invite, update), don't need to destroy/re-create.
      */
-    if (!call->med_orig || call->med_tp == call->med_orig) {
+    if (!call->med_orig) {
 
 	/* Check if SRTP requires secure signaling */
@@ -1211,4 +1219,6 @@
 	pjmedia_srtp_setting_default(&srtp_opt);
 	srtp_opt.close_member_tp = PJ_FALSE;
+        if (use_custom_med_tp)
+            custom_med_tp_flags |= PJSUA_MED_TP_CLOSE_MEMBER;
 	/* If media session has been ever established, let's use remote's 
 	 * preference in SRTP usage policy, especially when it is stricter.
@@ -1268,4 +1278,16 @@
     PJ_LOG(4,(THIS_FILE, "Media index %d selected for call %d",
 	      call->audio_idx, call->index));
+
+    if (use_custom_med_tp) {
+        /* Use custom media transport returned by the application */
+        call->med_tp = (*pjsua_var.ua_cfg.cb.on_create_media_transport)(
+                           call_id, call->audio_idx, call->med_tp,
+                           custom_med_tp_flags);
+        if (!call->med_tp) {
+	    if (sip_err_code) *sip_err_code = PJSIP_SC_NOT_ACCEPTABLE;
+	    pjsua_media_channel_deinit(call_id);
+	    return PJSIP_ERRNO_FROM_SIP_STATUS(PJSIP_SC_NOT_ACCEPTABLE);
+        }
+    }
 
     /* Create the media transport */
@@ -1544,4 +1566,5 @@
 	pjmedia_transport_close(call->med_tp);
 	call->med_tp = call->med_orig;
+        call->med_orig = NULL;
     }
 
