Index: /pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- /pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4668)
+++ /pjproject/branches/projects/pjsua2/pjsip-apps/src/swig/pjsua2.i	(revision 4669)
@@ -75,5 +75,6 @@
 %template(AudioMediaVector)		std::vector<pj::AudioMedia*>;
 %template(MediaFormatVector)		std::vector<pj::MediaFormat*>;
-%template(AudioDevInfoVector)	std::vector<AudioDevInfo*>;
+%template(AudioDevInfoVector)		std::vector<AudioDevInfo*>;
+%template(CodecInfoVector)		std::vector<pj::CodecInfo*>;
 
 %include "pjsua2/media.hpp"
Index: /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4668)
+++ /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/endpoint.hpp	(revision 4669)
@@ -1007,4 +1007,50 @@
     AudDevManager &audDevManager();
 
+    /*************************************************************************
+     * Codec management operations
+     */
+
+    /**
+     * Enum all supported codecs in the system.
+     *
+     * @return		Array of codec info.
+     */
+    const CodecInfoVector &codecEnum() throw(Error);
+
+    /**
+     * Change codec priority.
+     *
+     * @param codec_id	Codec ID, which is a string that uniquely identify
+     *			the codec (such as "speex/8000").
+     * @param priority	Codec priority, 0-255, where zero means to disable
+     *			the codec.
+     *
+     */
+    void codecSetPriority(const string &codec_id,
+			  pj_uint8_t priority) throw(Error);
+
+    /**
+     * Get codec parameters.
+     *
+     * @param codec_id		Codec ID.
+     *
+     * @return			Codec parameters. If codec is not found, Error
+     * 				will be thrown.
+     *
+     */
+    CodecParam codecGetParam(const string &codec_id) const throw(Error);
+
+    /**
+     * Set codec parameters.
+     *
+     * @param codec_id	Codec ID.
+     * @param param	Codec parameter to set. Set to NULL to reset
+     *			codec parameter to library default settings.
+     *
+     */
+    void codecSetParam(const string &codec_id,
+		       const CodecParam param) throw(Error);
+
+
 public:
     /*
@@ -1075,4 +1121,5 @@
     AudioMediaVector 	 	 mediaList;
     AudDevManager		 audioDevMgr;
+    CodecInfoVector		 codecInfoList;
 
     /* Endpoint static callbacks */
@@ -1197,4 +1244,7 @@
                               unsigned flags);
 
+private:
+    void clearCodecInfoList();
+
 };
 
Index: /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/media.hpp
===================================================================
--- /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/media.hpp	(revision 4668)
+++ /pjproject/branches/projects/pjsua2/pjsip/include/pjsua2/media.hpp	(revision 4669)
@@ -276,5 +276,5 @@
      * the media port from the conference bridge and Endpoint's media list.
      * Descendant should only call this method if it has registered the media
-     * with the previous call to #registerMediaPort().
+     * with the previous call to registerMediaPort().
      */
     void unregisterMediaPort();
@@ -432,5 +432,5 @@
 
     /**
-     * Device capabilities, as bitmask combination of #pjmedia_aud_dev_cap.
+     * Device capabilities, as bitmask combination of pjmedia_aud_dev_cap.
      */
     unsigned caps;
@@ -438,5 +438,5 @@
     /**
      * Supported audio device routes, as bitmask combination of
-     * #pjmedia_aud_dev_route. The value may be zero if the device
+     * pjmedia_aud_dev_route. The value may be zero if the device
      * does not support audio routing.
      */
@@ -562,7 +562,7 @@
      * Check whether the sound device is currently active. The sound device
      * may be inactive if the application has set the auto close feature to
-     * non-zero (the sndAutoCloseTime setting in #MediaConfig), or
+     * non-zero (the sndAutoCloseTime setting in MediaConfig), or
      * if null sound device or no sound device has been configured via the
-     * #setNoDev() function.
+     * setNoDev() function.
      */
     bool sndIsActive() const;
@@ -1054,4 +1054,43 @@
 };
 
+/*************************************************************************
+* Codec management
+*/
+
+/**
+ * This structure describes codec information.
+ */
+struct CodecInfo
+{
+    /**
+     * Codec unique identification.
+     */
+    string		codecId;
+
+    /**
+     * Codec priority (integer 0-255).
+     */
+    pj_uint8_t		priority;
+
+    /**
+     * Codec description.
+     */
+    string		desc;
+
+    /**
+     * Construct from pjsua_codec_info.
+     */
+    void fromPj(const pjsua_codec_info &codec_info);
+};
+
+/** Array of codec info */
+typedef std::vector<CodecInfo*> CodecInfoVector;
+
+/**
+ * Codec parameters, corresponds to pjmedia_codec_param or
+ * pjmedia_vid_codec_param.
+ */
+typedef void *CodecParam;
+
 } // namespace pj
 
Index: /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4668)
+++ /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/endpoint.cpp	(revision 4669)
@@ -32,4 +32,5 @@
 #define MAX_STUN_SERVERS	32
 #define TIMER_SIGNATURE		0x600D878A
+#define MAX_CODEC_NUM 		64
 
 struct UserTimer
@@ -376,4 +377,6 @@
     }
 
+    clearCodecInfoList();
+
     instance_ = NULL;
 }
@@ -1365,2 +1368,61 @@
     return audioDevMgr;
 }
+
+/*
+ * Codec operations.
+ */
+const CodecInfoVector &Endpoint::codecEnum() throw(Error)
+{
+    pjsua_codec_info pj_codec[MAX_CODEC_NUM];
+    unsigned count = 0;
+
+    PJSUA2_CHECK_EXPR( pjsua_enum_codecs(pj_codec, &count) );
+
+    clearCodecInfoList();
+
+    pj_enter_critical_section();
+    for (unsigned i=0;(i<count && i<MAX_CODEC_NUM);++i) {
+	CodecInfo *codec_info = new CodecInfo;
+
+	codec_info->fromPj(pj_codec[i]);
+	codecInfoList.push_back(codec_info);
+    }
+    pj_leave_critical_section();
+    return codecInfoList;
+}
+
+void Endpoint::codecSetPriority(const string &codec_id,
+			        pj_uint8_t priority) throw(Error)
+{
+    pj_str_t codec_str = str2Pj(codec_id);
+    PJSUA2_CHECK_EXPR( pjsua_codec_set_priority(&codec_str, priority) );
+}
+
+CodecParam Endpoint::codecGetParam(const string &codec_id) const throw(Error)
+{
+    pjmedia_codec_param *pj_param = NULL;
+    pj_str_t codec_str = str2Pj(codec_id);
+
+    PJSUA2_CHECK_EXPR( pjsua_codec_get_param(&codec_str, pj_param) );
+
+    return pj_param;
+}
+
+void Endpoint::codecSetParam(const string &codec_id,
+			     const CodecParam param) throw(Error)
+{
+    pj_str_t codec_str = str2Pj(codec_id);
+    pjmedia_codec_param *pj_param = (pjmedia_codec_param*)param;
+
+    PJSUA2_CHECK_EXPR( pjsua_codec_set_param(&codec_str, pj_param) );
+}
+
+void Endpoint::clearCodecInfoList()
+{
+    pj_enter_critical_section();
+    for (unsigned i=0;i<codecInfoList.size();++i) {
+	delete codecInfoList[i];
+    }
+    codecInfoList.clear();
+    pj_leave_critical_section();
+}
Index: /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/media.cpp
===================================================================
--- /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/media.cpp	(revision 4668)
+++ /pjproject/branches/projects/pjsua2/pjsip/src/pjsua2/media.cpp	(revision 4669)
@@ -386,8 +386,9 @@
     unsigned count;
 
+    PJSUA2_CHECK_EXPR( pjsua_enum_aud_devs(pj_info, &count) );
+
     clearAudioDevList();
 
-    PJSUA2_CHECK_EXPR( pjsua_enum_aud_devs(pj_info, &count) );
-
+    pj_enter_critical_section();
     for (unsigned i = 0; (i<count && i<MAX_DEV_COUNT) ;++i) {
 	AudioDevInfo *dev_info = new AudioDevInfo;
@@ -395,4 +396,5 @@
 	audioDevList.push_back(dev_info);
     }
+    pj_leave_critical_section();
     return audioDevList;
 }
@@ -691,8 +693,10 @@
 void AudDevManager::clearAudioDevList()
 {
+    pj_enter_critical_section();
     for(unsigned i=0;i<audioDevList.size();++i) {
 	delete audioDevList[i];
     }
     audioDevList.clear();
+    pj_leave_critical_section();
 }
 
@@ -704,2 +708,10 @@
     return is_capture?capture_dev:playback_dev;
 }
+
+///////////////////////////////////////////////////////////////////////////////
+void CodecInfo::fromPj(const pjsua_codec_info &codec_info)
+{
+    codecId = pj2Str(codec_info.codec_id);
+    priority = codec_info.priority;
+    desc = pj2Str(codec_info.desc);
+}
