Index: pjproject/trunk/pjmedia/src/pjmedia/rtcp_fb.c
===================================================================
--- pjproject/trunk/pjmedia/src/pjmedia/rtcp_fb.c	(revision 5827)
+++ pjproject/trunk/pjmedia/src/pjmedia/rtcp_fb.c	(revision 6106)
@@ -22,4 +22,5 @@
 #include <pjmedia/endpoint.h>
 #include <pjmedia/errno.h>
+#include <pjmedia/vid_codec.h>
 #include <pj/assert.h>
 #include <pj/log.h>
@@ -215,4 +216,5 @@
 {
     pj_bzero(opt, sizeof(*opt));
+    opt->dont_use_avpf = PJ_TRUE;
 
     return PJ_SUCCESS;
@@ -332,5 +334,10 @@
     pjmedia_codec_mgr *codec_mgr;
     unsigned j, cnt = 0;
+    pjmedia_type type = PJMEDIA_TYPE_UNKNOWN;
     pj_status_t status;
+
+    type = pjmedia_get_type(&m->desc.media);
+    if (type != PJMEDIA_TYPE_AUDIO && type != PJMEDIA_TYPE_VIDEO)
+	return PJMEDIA_EUNSUPMEDIATYPE;
 
     codec_mgr = pjmedia_endpt_get_codec_mgr(endpt);
@@ -339,11 +346,20 @@
 	pt = pj_strtoul(&m->desc.fmt[j]);
 	if (pt < 96) {
-	    const pjmedia_codec_info *ci;
-	    status = pjmedia_codec_mgr_get_codec_info(codec_mgr,
-						      pt, &ci);
-	    if (status != PJ_SUCCESS)
-		continue;
-
-	    pjmedia_codec_info_to_id(ci, sci[cnt].id, sizeof(sci[0].id));
+	    if (type == PJMEDIA_TYPE_AUDIO) {
+		const pjmedia_codec_info *ci;
+		status = pjmedia_codec_mgr_get_codec_info(codec_mgr, pt, &ci);
+		if (status != PJ_SUCCESS)
+		    continue;
+
+		pjmedia_codec_info_to_id(ci, sci[cnt].id, sizeof(sci[0].id));
+	    } else {
+		const pjmedia_vid_codec_info *ci;
+		status = pjmedia_vid_codec_mgr_get_codec_info(NULL, pt, &ci);
+		if (status != PJ_SUCCESS)
+		    continue;
+
+		pjmedia_vid_codec_info_to_id(ci, sci[cnt].id,
+					     sizeof(sci[0].id));
+	    }
 	} else {
 	    pjmedia_sdp_attr *a;
@@ -356,15 +372,24 @@
 	    if (status != PJ_SUCCESS)
 		continue;
-	    if (r.param.slen) {
+
+	    if (type == PJMEDIA_TYPE_AUDIO) {
+		/* Audio codec id format: "name/clock-rate/channel-count" */
+		if (r.param.slen) {
+		    pj_ansi_snprintf(sci[cnt].id, sizeof(sci[0].id),
+				     "%.*s/%d/%.*s",
+				     (int)r.enc_name.slen, r.enc_name.ptr,
+				     r.clock_rate,
+				     (int)r.param.slen, r.param.ptr);
+		} else {
+		    pj_ansi_snprintf(sci[cnt].id, sizeof(sci[0].id),
+				     "%.*s/%d/1",
+				     (int)r.enc_name.slen, r.enc_name.ptr,
+				     r.clock_rate);
+		}
+	    } else {
+		/* Video codec id format: "name/payload-type" */
 		pj_ansi_snprintf(sci[cnt].id, sizeof(sci[0].id),
-				 "%.*s/%d/%.*s",
-				 (int)r.enc_name.slen, r.enc_name.ptr,
-				 r.clock_rate,
-				 (int)r.param.slen, r.param.ptr);
-	    } else {
-		pj_ansi_snprintf(sci[cnt].id, sizeof(sci[0].id),
-				 "%.*s/%d/1",
-				 (int)r.enc_name.slen, r.enc_name.ptr,
-				 r.clock_rate);
+				 "%.*s/%d",
+				 (int)r.enc_name.slen, r.enc_name.ptr, pt);
 	    }
 	}
@@ -396,5 +421,5 @@
     PJ_UNUSED_ARG(sdp_remote);
 
-    PJ_ASSERT_RETURN(pool && endpt&& opt && sdp_local, PJ_EINVAL);
+    PJ_ASSERT_RETURN(pool && endpt && opt && sdp_local, PJ_EINVAL);
     PJ_ASSERT_RETURN(med_idx < sdp_local->media_count, PJ_EINVAL);
 
@@ -403,10 +428,8 @@
 	unsigned proto = pjmedia_sdp_transport_get_proto(&m->desc.transport);
 	if (!PJMEDIA_TP_PROTO_HAS_FLAG(proto, PJMEDIA_TP_PROFILE_RTCP_FB)) {
-	    char *new_tp;
-	    new_tp = (char*)pj_pool_zalloc(pool, m->desc.transport.slen+1);
-	    pj_ansi_strncpy(new_tp, m->desc.transport.ptr,
-			    m->desc.transport.slen);
-	    pj_ansi_strcat(new_tp, "F");
-	    pj_strset2(&m->desc.transport, new_tp);
+	    pj_str_t new_tp;
+	    pj_strdup_with_null(pool, &new_tp, &m->desc.transport);
+	    new_tp.ptr[new_tp.slen++] = 'F';
+	    m->desc.transport = new_tp;
 	}
     }
@@ -477,4 +500,20 @@
 				    pjmedia_rtcp_fb_info *info)
 {
+    return pjmedia_rtcp_fb_decode_sdp2(pool, endpt, opt, sdp, med_idx, -1,
+				       info);
+}
+
+/*
+ * Decode RTCP Feedback specific information from SDP media.
+ */
+PJ_DEF(pj_status_t) pjmedia_rtcp_fb_decode_sdp2(
+				    pj_pool_t *pool,
+				    pjmedia_endpt *endpt,
+				    const void *opt,
+				    const pjmedia_sdp_session *sdp,
+				    unsigned med_idx,
+				    int pt,
+				    pjmedia_rtcp_fb_info *info)
+{
     unsigned sci_cnt = PJMEDIA_MAX_SDP_FMT;
     sdp_codec_info_t sci[PJMEDIA_MAX_SDP_FMT];
@@ -487,4 +526,5 @@
     PJ_ASSERT_RETURN(pool && endpt && opt==NULL && sdp, PJ_EINVAL);
     PJ_ASSERT_RETURN(med_idx < sdp->media_count, PJ_EINVAL);
+    PJ_ASSERT_RETURN(pt <= 127, PJ_EINVAL);
 
     m = sdp->media[med_idx];
@@ -515,11 +555,12 @@
 
 	if (pj_strcmp2(&token, "*") == 0) {
-	    /* Asterisk (all codecs) */
+	    /* All codecs */
 	    codec_id = "*";
 	} else {
-	    /* Specific PT */
-	    unsigned pt = (unsigned) pj_strtoul2(&token, NULL, 10);
+	    /* Specific PT/codec */
+	    unsigned pt_ = (unsigned) pj_strtoul2(&token, NULL, 10);
 	    for (j = 0; j < sci_cnt; ++j) {
-		if (pt == sci[j].pt) {
+		/* Check if payload type is valid and requested */
+		if (pt_ == sci[j].pt && (pt < 0 || pt == (int)pt_)) {
 		    codec_id = sci[j].id;
 		    break;
@@ -528,5 +569,5 @@
 	}
 
-	/* Skip this a=rtcp-fb if PT is not recognized */
+	/* Skip this a=rtcp-fb if PT is not recognized or not requested */
 	if (!codec_id)
 	    continue;
