Index: pjproject/trunk/pjsip-apps/src/swig/symbols.i
===================================================================
--- pjproject/trunk/pjsip-apps/src/swig/symbols.i	(revision 5416)
+++ pjproject/trunk/pjsip-apps/src/swig/symbols.i	(revision 5417)
@@ -42,4 +42,6 @@
 
 typedef enum pjmedia_srtp_use {PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, PJMEDIA_SRTP_MANDATORY} pjmedia_srtp_use;
+
+typedef enum pjmedia_srtp_crypto_option {PJMEDIA_SRTP_NO_ENCRYPTION  = 1, PJMEDIA_SRTP_NO_AUTHENTICATION  = 2} pjmedia_srtp_crypto_option;
 
 typedef enum pjmedia_vid_stream_rc_method {PJMEDIA_VID_STREAM_RC_NONE = 0, PJMEDIA_VID_STREAM_RC_SIMPLE_BLOCKING = 1} pjmedia_vid_stream_rc_method;
Index: pjproject/trunk/pjsip-apps/src/swig/symbols.lst
===================================================================
--- pjproject/trunk/pjsip-apps/src/swig/symbols.lst	(revision 5416)
+++ pjproject/trunk/pjsip-apps/src/swig/symbols.lst	(revision 5417)
@@ -9,5 +9,5 @@
 
 pjmedia/event.h                 pjmedia_event_type
-pjmedia/transport_srtp.h	pjmedia_srtp_use
+pjmedia/transport_srtp.h	pjmedia_srtp_use pjmedia_srtp_crypto_option
 pjmedia/vid_stream.h		pjmedia_vid_stream_rc_method
 pjmedia-videodev/videodev.h	pjmedia_vid_dev_index pjmedia_vid_dev_std_index pjmedia_vid_dev_cap
Index: pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h
===================================================================
--- pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5416)
+++ pjproject/trunk/pjsip/include/pjsua-lib/pjsua.h	(revision 5417)
@@ -1367,4 +1367,21 @@
 
     /**
+     * This callback is called when SRTP media transport is created.
+     * Application can modify the SRTP setting \a srtp_opt to specify
+     * the cryptos and keys which are going to be used. Note that
+     * application should not modify the field
+     * \a pjmedia_srtp_setting.close_member_tp and can only modify
+     * the field \a pjmedia_srtp_setting.use for initial INVITE.
+     *
+     * @param call_id       Call ID
+     * @param media_idx     The media index in the SDP for which this SRTP
+     * 			    media transport will be used.
+     * @param srtp_opt      The SRTP setting. Application can modify this.
+     */
+    void (*on_create_media_transport_srtp)(pjsua_call_id call_id,
+                                           unsigned media_idx,
+                                           pjmedia_srtp_setting *srtp_opt);
+
+    /**
      * This callback can be used by application to override the account
      * to be used to handle an incoming message. Initially, the account to
Index: pjproject/trunk/pjsip/include/pjsua2/call.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5416)
+++ pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5417)
@@ -950,4 +950,52 @@
      */
     unsigned        flags;
+};
+
+/**
+ * SRTP crypto.
+ */
+struct SrtpCrypto
+{
+    /**
+     * Optional key. If empty, a random key will be autogenerated.
+     */
+    string	key;
+
+    /**
+     * Crypto name.
+     */
+    string	name;
+
+    /**
+     * Flags, bitmask from #pjmedia_srtp_crypto_option
+     */
+    unsigned	flags;
+};
+
+/**
+ * This structure contains parameters for Call::onCreateMediaTransportSrtp()
+ * callback.
+ */
+struct OnCreateMediaTransportSrtpParam
+{
+    /**
+     * The media index in the SDP for which the SRTP media transport
+     * will be used.
+     */
+    unsigned        		mediaIdx;
+    
+    /**
+     * Specify whether secure media transport should be used. Application
+     * can modify this only for initial INVITE.
+     * Valid values are PJMEDIA_SRTP_DISABLED, PJMEDIA_SRTP_OPTIONAL, and
+     * PJMEDIA_SRTP_MANDATORY.
+     */
+    pjmedia_srtp_use		srtpUse;
+    
+    /**
+     * Application can modify this to specify the cryptos and keys
+     * which are going to be used.
+     */
+    vector<SrtpCrypto>		cryptos;
 };
 
@@ -1744,4 +1792,18 @@
     { PJ_UNUSED_ARG(prm); }
 
+    /**
+     * This callback is called when SRTP media transport is created.
+     * Application can modify the SRTP setting \a srtpOpt to specify
+     * the cryptos and keys which are going to be used. Note that
+     * application should not modify the field
+     * \a pjmedia_srtp_setting.close_member_tp and can only modify
+     * the field \a pjmedia_srtp_setting.use for initial INVITE.
+     *
+     * @param prm	Callback parameter.
+     */
+    virtual void
+    onCreateMediaTransportSrtp(OnCreateMediaTransportSrtpParam &prm)
+    { PJ_UNUSED_ARG(prm); }
+
 private:
     Account             &acc;
Index: pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5416)
+++ pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5417)
@@ -1403,4 +1403,8 @@
                               pjmedia_transport *base_tp,
                               unsigned flags);
+    static void
+    on_create_media_transport_srtp(pjsua_call_id call_id,
+                                   unsigned media_idx,
+                                   pjmedia_srtp_setting *srtp_opt);
 
 private:
Index: pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c
===================================================================
--- pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5416)
+++ pjproject/trunk/pjsip/src/pjsua-lib/pjsua_media.c	(revision 5417)
@@ -1481,4 +1481,20 @@
 	else
 	    srtp_opt.use = acc->cfg.use_srtp;
+	    
+	if (pjsua_var.ua_cfg.cb.on_create_media_transport_srtp) {
+	    pjsua_call *call = call_med->call;
+	    pjmedia_srtp_use srtp_use = srtp_opt.use;
+
+	    (*pjsua_var.ua_cfg.cb.on_create_media_transport_srtp)
+		(call->index, call_med->idx, &srtp_opt);
+
+	    /* Close_member_tp must not be overwritten by app */
+	    srtp_opt.close_member_tp = PJ_TRUE;
+
+	    /* Revert SRTP usage policy if media is reinitialized */
+	    if (call->inv && call->inv->state == PJSIP_INV_STATE_CONFIRMED) {
+		srtp_opt.use = srtp_use;
+	    }
+    	}
 
 	status = pjmedia_transport_srtp_create(pjsua_var.med_endpt,
Index: pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5416)
+++ pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5417)
@@ -1267,4 +1267,51 @@
 }
 
+void Endpoint::on_create_media_transport_srtp(pjsua_call_id call_id,
+                                    	      unsigned media_idx,
+                                    	      pjmedia_srtp_setting *srtp_opt)
+{
+    Call *call = Call::lookup(call_id);
+    if (!call) {
+	pjsua_call *in_call = &pjsua_var.calls[call_id];
+	if (in_call->incoming_data) {
+	    /* This can happen when there is an incoming call but the
+	     * on_incoming_call() callback hasn't been called. So we need to 
+	     * call the callback here.
+	     */
+	    on_incoming_call(in_call->acc_id, call_id, in_call->incoming_data);
+
+	    /* New call should already be created by app. */
+	    call = Call::lookup(call_id);
+	    if (!call) {
+		return;
+	    }
+	} else {
+	    return;
+	}
+    }
+    
+    OnCreateMediaTransportSrtpParam prm;
+    prm.mediaIdx = media_idx;
+    prm.srtpUse  = srtp_opt->use;
+    for (int i = 0; i < srtp_opt->crypto_count; i++) {
+    	SrtpCrypto crypto;
+    	
+    	crypto.key   = pj2Str(srtp_opt->crypto[i].key);
+    	crypto.name  = pj2Str(srtp_opt->crypto[i].name);
+    	crypto.flags = srtp_opt->crypto[i].flags;
+    	prm.cryptos.push_back(crypto);
+    }
+    
+    call->onCreateMediaTransportSrtp(prm);
+    
+    srtp_opt->use = prm.srtpUse;
+    srtp_opt->crypto_count = prm.cryptos.size();
+    for (int i = 0; i < srtp_opt->crypto_count; i++) {
+    	srtp_opt->crypto[i].key   = str2Pj(prm.cryptos[i].key);
+    	srtp_opt->crypto[i].name  = str2Pj(prm.cryptos[i].name);
+    	srtp_opt->crypto[i].flags = prm.cryptos[i].flags;
+    }    
+}
+
 ///////////////////////////////////////////////////////////////////////////////
 /*
