Index: /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i
===================================================================
--- /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 5164)
+++ /pjproject/trunk/pjsip-apps/src/swig/pjsua2.i	(revision 5165)
@@ -113,4 +113,5 @@
 %template(CodecInfoVector)		std::vector<pj::CodecInfo*>;
 %template(VideoDevInfoVector)		std::vector<pj::VideoDevInfo*>;
+%template(CodecFmtpVector)		std::vector<pj::CodecFmtp>;	
 
 /* pj::WindowHandle::setWindow() receives Surface object */
Index: /pjproject/trunk/pjsip-apps/src/swig/symbols.i
===================================================================
--- /pjproject/trunk/pjsip-apps/src/swig/symbols.i	(revision 5164)
+++ /pjproject/trunk/pjsip-apps/src/swig/symbols.i	(revision 5165)
@@ -98,4 +98,6 @@
 typedef enum pjmedia_format_id {PJMEDIA_FORMAT_L16 = 0, PJMEDIA_FORMAT_PCM = PJMEDIA_FORMAT_L16, PJMEDIA_FORMAT_PCMA = ((('W' << 24) | ('A' << 16)) | ('L' << 8)) | 'A', PJMEDIA_FORMAT_ALAW = PJMEDIA_FORMAT_PCMA, PJMEDIA_FORMAT_PCMU = ((('W' << 24) | ('A' << 16)) | ('L' << 8)) | 'u', PJMEDIA_FORMAT_ULAW = PJMEDIA_FORMAT_PCMU, PJMEDIA_FORMAT_AMR = ((('R' << 24) | ('M' << 16)) | ('A' << 8)) | ' ', PJMEDIA_FORMAT_G729 = ((('9' << 24) | ('2' << 16)) | ('7' << 8)) | 'G', PJMEDIA_FORMAT_ILBC = ((('C' << 24) | ('B' << 16)) | ('L' << 8)) | 'I', PJMEDIA_FORMAT_RGB24 = ((('3' << 24) | ('B' << 16)) | ('G' << 8)) | 'R', PJMEDIA_FORMAT_RGBA = ((('A' << 24) | ('B' << 16)) | ('G' << 8)) | 'R', PJMEDIA_FORMAT_BGRA = ((('A' << 24) | ('R' << 16)) | ('G' << 8)) | 'B', PJMEDIA_FORMAT_RGB32 = PJMEDIA_FORMAT_RGBA, PJMEDIA_FORMAT_DIB = (((' ' << 24) | ('B' << 16)) | ('I' << 8)) | 'D', PJMEDIA_FORMAT_GBRP = ((('P' << 24) | ('R' << 16)) | ('B' << 8)) | 'G', PJMEDIA_FORMAT_AYUV = ((('V' << 24) | ('U' << 16)) | ('Y' << 8)) | 'A', PJMEDIA_FORMAT_YUY2 = ((('2' << 24) | ('Y' << 16)) | ('U' << 8)) | 'Y', PJMEDIA_FORMAT_UYVY = ((('Y' << 24) | ('V' << 16)) | ('Y' << 8)) | 'U', PJMEDIA_FORMAT_YVYU = ((('U' << 24) | ('Y' << 16)) | ('V' << 8)) | 'Y', PJMEDIA_FORMAT_I420 = ((('0' << 24) | ('2' << 16)) | ('4' << 8)) | 'I', PJMEDIA_FORMAT_IYUV = PJMEDIA_FORMAT_I420, PJMEDIA_FORMAT_YV12 = ((('2' << 24) | ('1' << 16)) | ('V' << 8)) | 'Y', PJMEDIA_FORMAT_NV21 = ((('1' << 24) | ('2' << 16)) | ('V' << 8)) | 'N', PJMEDIA_FORMAT_I422 = ((('2' << 24) | ('2' << 16)) | ('4' << 8)) | 'I', PJMEDIA_FORMAT_I420JPEG = ((('0' << 24) | ('2' << 16)) | ('4' << 8)) | 'J', PJMEDIA_FORMAT_I422JPEG = ((('2' << 24) | ('2' << 16)) | ('4' << 8)) | 'J', PJMEDIA_FORMAT_H261 = ((('1' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_H263 = ((('3' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_H263P = ((('3' << 24) | ('6' << 16)) | ('2' << 8)) | 'P', PJMEDIA_FORMAT_H264 = ((('4' << 24) | ('6' << 16)) | ('2' << 8)) | 'H', PJMEDIA_FORMAT_MJPEG = ((('G' << 24) | ('P' << 16)) | ('J' << 8)) | 'M', PJMEDIA_FORMAT_MPEG1VIDEO = ((('V' << 24) | ('1' << 16)) | ('P' << 8)) | 'M', PJMEDIA_FORMAT_MPEG2VIDEO = ((('V' << 24) | ('2' << 16)) | ('P' << 8)) | 'M', PJMEDIA_FORMAT_MPEG4 = ((('4' << 24) | ('G' << 16)) | ('P' << 8)) | 'M'} pjmedia_format_id;
 
+typedef enum pjmedia_vid_packing {PJMEDIA_VID_PACKING_UNKNOWN, PJMEDIA_VID_PACKING_PACKETS = 1, PJMEDIA_VID_PACKING_WHOLE = 2} pjmedia_vid_packing;
+
 typedef enum pjsip_cred_data_type {PJSIP_CRED_DATA_PLAIN_PASSWD = 0, PJSIP_CRED_DATA_DIGEST = 1, PJSIP_CRED_DATA_EXT_AKA = 16} pjsip_cred_data_type;
 
Index: /pjproject/trunk/pjsip-apps/src/swig/symbols.lst
===================================================================
--- /pjproject/trunk/pjsip-apps/src/swig/symbols.lst	(revision 5164)
+++ /pjproject/trunk/pjsip-apps/src/swig/symbols.lst	(revision 5165)
@@ -17,4 +17,5 @@
 pjmedia/types.h                 pjmedia_type pjmedia_dir pjmedia_tp_proto pjmedia_orient
 pjmedia/format.h		pjmedia_format_id
+pjmedia/vid_codec.h		pjmedia_vid_packing
 
 pjsip/sip_auth.h		pjsip_cred_data_type
Index: /pjproject/trunk/pjsip/include/pjsua2/call.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5164)
+++ /pjproject/trunk/pjsip/include/pjsua2/call.hpp	(revision 5165)
@@ -46,10 +46,4 @@
 
 //////////////////////////////////////////////////////////////////////////////
-
-/**
- * Codec parameters, corresponds to pjmedia_codec_param or
- * pjmedia_vid_codec_param.
- */
-typedef void *CodecParam;
 
 /**
Index: /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5164)
+++ /pjproject/trunk/pjsip/include/pjsua2/endpoint.hpp	(revision 5165)
@@ -1151,5 +1151,5 @@
      *
      */
-    CodecParam videoCodecGetParam(const string &codec_id) const throw(Error);
+    VidCodecParam getVideoCodecParam(const string &codec_id) const throw(Error);
 
     /**
@@ -1157,10 +1157,17 @@
      *
      * @param codec_id	Codec ID.
-     * @param param	Codec parameter to set. Set to NULL to reset
-     *			codec parameter to library default settings.
-     *
-     */
-    void videoCodecSetParam(const string &codec_id,
-			    const CodecParam param) throw(Error);
+     * @param param	Codec parameter to set.
+     *
+     */
+    void setVideoCodecParam(const string &codec_id,
+			    const VidCodecParam &param) throw(Error);
+			    
+    /**
+     * Reset video codec parameters to library default settings.
+     *
+     * @param codec_id	Codec ID.
+     *
+     */
+    void resetVideoCodecParam(const string &codec_id) throw(Error);
 
 public:
Index: /pjproject/trunk/pjsip/include/pjsua2/media.hpp
===================================================================
--- /pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 5164)
+++ /pjproject/trunk/pjsip/include/pjsua2/media.hpp	(revision 5165)
@@ -1942,9 +1942,62 @@
 
 /**
- * Codec parameters, corresponds to pjmedia_codec_param or
- * pjmedia_vid_codec_param.
+ * Codec parameters, corresponds to pjmedia_codec_param.
  */
 typedef void *CodecParam;
 
+/**
+ * Structure of codec specific parameters which contains name=value pairs.
+ * The codec specific parameters are to be used with SDP according to
+ * the standards (e.g: RFC 3555) in SDP 'a=fmtp' attribute.
+ */
+typedef struct CodecFmtp
+{
+    string name;
+    string val;
+} CodecFmtp;
+
+/** Array of codec fmtp */
+typedef std::vector<CodecFmtp> CodecFmtpVector;
+
+/**
+ * Detailed codec attributes used in configuring a codec and in querying
+ * the capability of codec factories. 
+ *
+ * Please note that codec parameter also contains SDP specific setting,
+ * #decFmtp and #encFmtp, which may need to be set appropriately based on
+ * the effective setting. See each codec documentation for more detail.
+ */
+struct VidCodecParam
+{
+    pjmedia_dir         dir;            /**< Direction                      */
+    pjmedia_vid_packing packing; 	/**< Packetization strategy.	    */
+
+    struct
+    MediaFormatVideo    encFmt;         /**< Encoded format	            */
+    CodecFmtpVector	encFmtp;        /**< Encoder fmtp params	    */
+    unsigned            encMtu;         /**< MTU or max payload size setting*/
+
+    struct
+    MediaFormatVideo    decFmt;         /**< Decoded format	            */
+    CodecFmtpVector	decFmtp;        /**< Decoder fmtp params	    */
+
+    bool		ignoreFmtp;	/**< Ignore fmtp params. If set to
+					     true, the codec will apply
+					     format settings specified in
+					     encFmt and decFmt only.	    */
+
+    void fromPj(const pjmedia_vid_codec_param &param);
+
+    pjmedia_vid_codec_param toPj() const;
+
+private:
+    void setCodecFmtp(const pjmedia_codec_fmtp &in_fmtp, 
+		      CodecFmtpVector &out_fmtp);
+
+    void getCodecFmtp(const CodecFmtpVector &in_fmtp,
+		      pjmedia_codec_fmtp &out_fmtp) const;
+
+};
+
 
 /**
Index: /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5164)
+++ /pjproject/trunk/pjsip/src/pjsua2/endpoint.cpp	(revision 5165)
@@ -1684,5 +1684,5 @@
 
 	codec_info->fromPj(pj_codec[i]);
-	codecInfoList.push_back(codec_info);
+	codec_list.push_back(codec_info);
     }
     pj_leave_critical_section();
@@ -1699,5 +1699,5 @@
     updateCodecInfoList(pj_codec, count, videoCodecInfoList);
 #endif
-    return codecInfoList;
+    return videoCodecInfoList;
 }
 
@@ -1714,26 +1714,28 @@
 }
 
-CodecParam Endpoint::videoCodecGetParam(const string &codec_id) const
-	   throw(Error)
-{
-    pjmedia_vid_codec_param *pj_param = NULL;
+VidCodecParam Endpoint::getVideoCodecParam(const string &codec_id) const 
+								   throw(Error)
+{    
+    VidCodecParam codec_param;
 #if PJSUA_HAS_VIDEO
-    pj_str_t codec_str = str2Pj(codec_id);
-
-    PJSUA2_CHECK_EXPR(pjsua_vid_codec_get_param(&codec_str, pj_param));
+    pjmedia_vid_codec_param pj_param;
+    pj_str_t codec_str = str2Pj(codec_id);    
+
+    PJSUA2_CHECK_EXPR(pjsua_vid_codec_get_param(&codec_str, &pj_param));
+    codec_param.fromPj(pj_param);
 #else
     PJ_UNUSED_ARG(codec_id);
 #endif
-    return pj_param;
-}
-
-void Endpoint::videoCodecSetParam(const string &codec_id,
-				  const CodecParam param) throw(Error)
+    return codec_param;
+}
+
+void Endpoint::setVideoCodecParam(const string &codec_id,
+				  const VidCodecParam &param) throw(Error)
 {
 #if PJSUA_HAS_VIDEO
     pj_str_t codec_str = str2Pj(codec_id);
-    pjmedia_vid_codec_param *pj_param = (pjmedia_vid_codec_param*)param;
-
-    PJSUA2_CHECK_EXPR(pjsua_vid_codec_set_param(&codec_str, pj_param));
+    pjmedia_vid_codec_param pj_param = param.toPj();
+    
+    PJSUA2_CHECK_EXPR(pjsua_vid_codec_set_param(&codec_str, &pj_param));
 #else
     PJ_UNUSED_ARG(codec_id);
@@ -1742,2 +1744,13 @@
 }
 
+void Endpoint::resetVideoCodecParam(const string &codec_id) throw(Error)
+{
+#if PJSUA_HAS_VIDEO
+    pj_str_t codec_str = str2Pj(codec_id);    
+    
+    PJSUA2_CHECK_EXPR(pjsua_vid_codec_set_param(&codec_str, NULL));
+#else
+    PJ_UNUSED_ARG(codec_id);
+    PJ_UNUSED_ARG(param);
+#endif	
+}
Index: /pjproject/trunk/pjsip/src/pjsua2/media.cpp
===================================================================
--- /pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 5164)
+++ /pjproject/trunk/pjsip/src/pjsua2/media.cpp	(revision 5165)
@@ -1507,2 +1507,57 @@
     desc = pj2Str(codec_info.desc);
 }
+
+void VidCodecParam::fromPj(const pjmedia_vid_codec_param &param)
+{
+    dir = param.dir;
+    packing = param.packing;
+    ignoreFmtp = param.ignore_fmtp;
+    encMtu = param.enc_mtu;
+    encFmt.fromPj(param.enc_fmt);
+    decFmt.fromPj(param.dec_fmt);
+    setCodecFmtp(param.enc_fmtp, encFmtp);
+    setCodecFmtp(param.dec_fmtp, decFmtp);
+}
+
+pjmedia_vid_codec_param VidCodecParam::toPj() const
+{
+    pjmedia_vid_codec_param param;
+    pj_bzero(&param, sizeof(param));    
+    param.dir = dir;
+    param.packing = packing;
+    param.ignore_fmtp = ignoreFmtp;
+    param.enc_mtu = encMtu;
+    param.enc_fmt = encFmt.toPj();
+    param.dec_fmt = decFmt.toPj();
+    getCodecFmtp(encFmtp, param.enc_fmtp);    
+    getCodecFmtp(decFmtp, param.dec_fmtp);
+    return param;
+}
+
+void VidCodecParam::setCodecFmtp(const pjmedia_codec_fmtp &in_fmtp, 
+				 CodecFmtpVector &out_fmtp)
+{
+    unsigned i = 0;
+    for ( ; i<in_fmtp.cnt; ++i) {
+	CodecFmtp fmtp;
+	fmtp.name = pj2Str(in_fmtp.param[i].name);
+	fmtp.val = pj2Str(in_fmtp.param[i].val);
+
+	out_fmtp.push_back(fmtp);
+    }
+}
+
+void VidCodecParam::getCodecFmtp(const CodecFmtpVector &in_fmtp,
+				 pjmedia_codec_fmtp &out_fmtp) const
+{
+    CodecFmtpVector::const_iterator i;
+    out_fmtp.cnt = 0;    
+    for (i=in_fmtp.begin(); i!=in_fmtp.end();++i) {
+	if (out_fmtp.cnt >= PJMEDIA_CODEC_MAX_FMTP_CNT) {
+	    break;
+	}
+	out_fmtp.param[out_fmtp.cnt].name = str2Pj((*i).name);
+	out_fmtp.param[out_fmtp.cnt].val = str2Pj((*i).val);
+	++out_fmtp.cnt;
+    }
+}
