[asterisk-commits] oej: branch oej/videocaps r101343 - in /team/oej/videocaps: channels/ include...

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Wed Jan 30 15:27:30 CST 2008


Author: oej
Date: Wed Jan 30 15:27:30 2008
New Revision: 101343

URL: http://svn.digium.com/view/asterisk?view=rev&rev=101343
Log:
Adding MPEG4 and H264 plus to videocaps
	code from neutrino88 - thanks!!!
(closes issue #11881)
Reported by: neutrino88
Patches: 
      capability.c uploaded by neutrino88 (license 297)
      capability.h uploaded by neutrino88 (license 297)
      chan_sip.c uploaded by neutrino88 (license 297)
      channel.h uploaded by neutrino88 (license 297)
      channel.c uploaded by neutrino88 (license 297)


Modified:
    team/oej/videocaps/channels/chan_sip.c
    team/oej/videocaps/include/asterisk/capability.h
    team/oej/videocaps/include/asterisk/channel.h
    team/oej/videocaps/main/Makefile
    team/oej/videocaps/main/capability.c
    team/oej/videocaps/main/channel.c

Modified: team/oej/videocaps/channels/chan_sip.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/channels/chan_sip.c?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/channels/chan_sip.c (original)
+++ team/oej/videocaps/channels/chan_sip.c Wed Jan 30 15:27:30 2008
@@ -1715,6 +1715,7 @@
 static int sip_senddigit_begin(struct ast_channel *ast, char digit);
 static int sip_senddigit_end(struct ast_channel *ast, char digit, unsigned int duration);
 static const char *sip_get_callid(struct ast_channel *chan);
+static int sip_get_negotiated_caps(struct ast_channel *ast, struct ast_capabilities *jcaps);
 
 static int handle_request_do(struct sip_request *req, struct sockaddr_in *sin);
 static int sip_standard_port(struct sip_socket s);
@@ -1791,6 +1792,7 @@
 static int process_sdp(struct sip_pvt *p, struct sip_request *req, int t38action);
 static void ast_build_h2613_fmtp(struct ast_str **buf, int rtp_code, struct ast_h2613_video_cap *video_cap);
 static void ast_build_h264_fmtp(struct ast_str **buf, int rtp_code, struct ast_h264_video_cap *video_cap);
+static void ast_build_mp4v_fmtp(struct ast_str **buf, int rtp_code, struct ast_h264_video_cap *video_cap);
 static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
 			     struct ast_str **m_buf, struct ast_str **a_buf,
 			     int debug, int *min_packet_size);
@@ -2079,6 +2081,7 @@
 	.early_bridge = ast_rtp_early_bridge,
 	.send_text = sip_sendtext,		/* called with chan locked */
 	.set_capabilities = sip_set_capabilities,
+	.get_negotiated_caps = sip_get_negotiated_caps,	
 	.func_channel_read = acf_channel_read,
 	.get_pvt_uniqueid = sip_get_callid,
 };
@@ -4867,7 +4870,15 @@
 	return res;
 }
 
-/*! \brief  sip_set_capabilities: called when channel needs to have caps updated from another channel
+/*! \brief Get prefered codecs to send back to the calling party */
+static int sip_get_negotiated_caps(struct ast_channel *ast, struct ast_capabilities *jcaps)
+{
+	int dst = jcaps->cap = ast->nativeformats;
+
+	return dst;	
+}
+
+/*! \brief  Called when channel needs to have caps updated from another channel
 	When * is making an outgoing call, the confcaps will be set (sip_new has already been called) but
    	jointcaps and peer caps will be zero
 	On the REVERSE cap exchange we'll need to do a MIN(joint, chancap); 
@@ -6824,7 +6835,16 @@
 							break;
 						case '3' :
 							/* ast_verbose("Found a H.263 media type\n");*/
-							p->peercaps.h263.valid = 1;
+							if (mimeSubtype[4]) {
+								if (!strcasecmp(mimeSubtype, "H263-1998")){
+									p->peercaps.h263p.valid = 1;
+								} else {
+									ast_verbose("Found unsupported media type\n");
+								}
+							} else {
+								p->peercaps.h263.valid = 1;
+							}
+							break;
 							break;
 						case '4' :
 							/* ast_verbose("Found a H.264 media type\n"); */
@@ -6836,7 +6856,14 @@
 							break;
 					}
 				}
-			} else if (!strncasecmp(mimeSubtype, "T140",4)) { /* Text */
+			} else if (!strncasecmp(mimeSubtype, "MP4V", 4)) {			
+                                if (p->vrtp) {
+                                        ast_verbose("----- Adding video (%d) mimeSubtype (%s) to videortp struct\n", codec, mimeSubtype);
+                                        ast_rtp_set_rtpmap_type(newvideortp, codec, "video", mimeSubtype, 0);
+					p->peercaps.mp4v.valid = 1;
+					p->peercaps.mp4v.rtpnum = codec;
+                                }
+			} else if (!strncasecmp(mimeSubtype, "T140", 4)) { /* Text */
 				if (p->trtp) {
 					/* ast_verbose("Adding t140 mimeSubtype to textrtp struct\n"); */
 					ast_rtp_set_rtpmap_type(newtextrtp, codec, "text", mimeSubtype, 0);
@@ -6881,6 +6908,14 @@
 				case AST_FORMAT_H264:
 					a += len;
 					process_h264_fmtp(a, &p->peercaps.h264, framerate);
+					break;
+				case AST_FORMAT_H263_PLUS:
+					a += len;
+                                        parse_h2613_conf_line(a, &p->peercaps.h263p, framerate);
+					break;
+				case AST_FORMAT_MP4_VIDEO:
+					a += len;
+                                        parse_mp4v_conf_line(a, &p->peercaps.mp4v, framerate);
 					break;
 				default:
 					if (option_debug > 1) {
@@ -7932,24 +7967,58 @@
 	return 0;
 }
 
-/*! \brief Build fmtp headers for H261, H263 video */
+/*! \brief Build fmtp headers for H261, H263, H263+ video */
 static void ast_build_h2613_fmtp(struct ast_str **buf, int rtp_code, struct ast_h2613_video_cap *video_cap)
 {
-	int i;
-	
-	if(video_cap->valid) {
-		ast_str_append(buf, 0, "a=fmtp:%d ",rtp_code);
-		for (i = 0; i < MAX_VIDEO_SIZES; i++) {
-	  		if (video_cap->maxfr[i] > 0)
-				ast_str_append(buf, 0, "%s=%d ", videoSizes[i].type, 30/video_cap->maxfr[i]);
-	  	}
-		if (video_cap->maxbr > 0)
-	  		ast_str_append(buf, 0, "maxbr=%d",video_cap->maxbr/100);
+        int i;
+	char tab[30]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+	unsigned char comp=0xFF;
+	int mask=1;
+	int init=1;
+
+	if (!video_cap->valid) {
+                ast_debug(1, "WARNING Video cap is not valid but have been asked to add fmtp\n");
+                ast_str_append(buf, 0, "a=fmtp:%d;CIF=1;QCIF=1;maxbr=3840\r\n", rtp_code);
+		return;
+	}
+	for (i = 0; i < MAX_VIDEO_SIZES; i++) {
+		if (video_cap->maxfr[i] > 0) {
+			if (init)
+				ast_str_append(buf, 0, "a=fmtp:%d ", rtp_code);
+			ast_str_append(buf, 0, "%s%s=%d", init ? "" : ";" ,videoSizes[i].type, 30/video_cap->maxfr[i]);
+			init=0;
+		}
+	}
+	if (video_cap->maxbr > 0) {
+		if (init)
+			ast_str_append(buf, 0, "a=fmtp:%d ",rtp_code);
+		ast_str_append(buf, 0, "%smaxbr=%d", init ? "" : ";" , video_cap->maxbr/100);
+		init=0;
+	}
+	if (video_cap->annexes){ /* h263+ */
+		if (init)
+			ast_str_append(buf, 0, "a=fmtp:%d ",rtp_code);
+		for (i=0; i<26; i++) {
+			if (mask&video_cap->annexes) {
+				ast_str_append(buf, 0, "%s%c=%d", init ? "" : ";" ,tab[i], tab[i] == 'N' ? 4:1);
+				init=0;
+			}
+			mask=mask<<1;
+		}
+  	}
+	if (video_cap->profile != comp) { /* h263+ */
+		if (init)
+			ast_str_append(buf, 0, "a=fmtp:%d ",rtp_code);
+     		ast_str_append(buf, 0, "%sprofile=%x; ", init ? "" : ";" , video_cap->profile);
+		init=0;
+  	}
+	if (video_cap->level != comp) { /*h263+ */
+		if (init)
+			ast_str_append(buf, 0, "a=fmtp:%d ",rtp_code);
+		ast_str_append(buf, 0, "level=%02x",video_cap->level);
+	}
+	if (!init)
 		ast_str_append(buf, 0, "\r\n");
-	} else {
-		ast_verbose("WARNING Video cap is not valid but have been asked to add fmtp\n");
-		ast_str_append(buf, 0, "a=fmtp:%d;CIF=1;QCIF=1;maxbr=3840\r\n", rtp_code);
-	}
 }
 
 /*! \brief Build fmtp headers for H264 video */
@@ -7957,16 +8026,41 @@
 {
 	/* ast_build_string(a_buf, a_size, "a=fmtp:%d profile-level-id=42800C; packetization-mode=0; max-br=384; max-mbps=10000\r\n", rtp_code); */
 	
-	if(video_cap->valid) {
-		ast_str_append(buf, 0, "a=fmtp:%d ", rtp_code);
-		ast_str_append(buf, 0, "profile-level-id=42800C; packetization-mode=0; ");
-		if (video_cap->maxmbps > 0)
-			ast_str_append(buf, 0, "max-mbps=%d; ",video_cap->maxmbps);
-		if (video_cap->maxbr > 0)
-			ast_str_append(buf, 0, "max-br=%d",video_cap->maxbr/1000);
-		ast_str_append(buf, 0, "\r\n");
-	}
-}
+	if(!video_cap->valid) {
+                ast_debug(1, "WARNING Video cap is not valid but have been asked to add fmtp\n");
+                ast_str_append(buf, 0, "a=fmtp:%d profile-level-id=420033; packetization-mode=0\r\n", rtp_code);
+		return;
+	}
+	ast_str_append(buf, 0, "a=fmtp:%d ", rtp_code);
+	ast_str_append(buf, 0, "profile-level-id=42800C; packetization-mode=0; ");
+	if (video_cap->maxmbps > 0)
+		ast_str_append(buf, 0, "max-mbps=%d; ", video_cap->maxmbps);
+	if (video_cap->maxbr > 0)
+		ast_str_append(buf, 0, "max-br=%d", video_cap->maxbr/1000);
+	ast_str_append(buf, 0, "\r\n");
+}
+
+/*! \brief Build fmtp headers for MPEG4 video */
+static void ast_build_mp4v_fmtp(struct ast_str **buf, int rtp_code, struct ast_h264_video_cap *video_cap)
+{
+	
+	int profile_level = 0;
+
+	if (!video_cap->valid) {
+		ast_debug(1, "WARNING Video cap is not valid but have been asked to add fmtp\n");
+		ast_str_append(buf, 0, "a=fmtp:%d profile-level-id=1\r\n", rtp_code);
+		return;
+	}
+        ast_str_append(buf, 0, "a=fmtp:%d ", rtp_code);
+	profile_level = video_cap->profile<<4 | video_cap->level; 
+        ast_str_append(buf, 0, "profil-level-id=%d",profile_level);
+        if (video_cap->maxmbps > 0)
+		ast_str_append(buf, 0, "max-mbps=%d; ", video_cap->maxmbps);
+	if (video_cap->maxbr > 0)
+		ast_str_append(buf, 0, "max-br=%d", video_cap->maxbr/1000);
+	ast_str_append(buf, 0, "\r\n");
+}
+
 
 /*! \brief Add codec offer to SDP offer/answer body in INVITE or 200 OK */
 static void add_codec_to_sdp(const struct sip_pvt *p, int codec, int sample_rate,
@@ -8042,6 +8136,14 @@
 			ast_verbose("Adding h264 fmtp with rtpnum %d\n", p->jointcaps.h264.rtpnum);
 		}
 		ast_build_h264_fmtp(a_buf, rtp_code, (struct ast_h264_video_cap*)&p->jointcaps.h264);
+        } else if (codec == AST_FORMAT_MP4_VIDEO) {
+		if (sipdebug_caps)
+                        ast_verbose("Adding MP4v fmtp with rtpnum %d\n",p->jointcaps.mp4v.rtpnum);
+                ast_build_mp4v_fmtp(a_buf, rtp_code, (struct ast_h264_video_cap*)&p->jointcaps.mp4v);
+	} else if (codec == AST_FORMAT_H263_PLUS) {
+                if (sipdebug_caps)
+                        ast_verbose("Adding H263+ fmtp with rtpnum %d\n",p->jointcaps.mp4v.rtpnum);
+                ast_build_h2613_fmtp(a_buf, rtp_code, (struct ast_h2613_video_cap*)&p->jointcaps.h263p);
 	}
 	/*! /todo Room for MPEG4 */
 

Modified: team/oej/videocaps/include/asterisk/capability.h
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/include/asterisk/capability.h?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/include/asterisk/capability.h (original)
+++ team/oej/videocaps/include/asterisk/capability.h Wed Jan 30 15:27:30 2008
@@ -45,15 +45,20 @@
  *	In this file, we specify attributes structures to handle a range of video
  *	codecs
  *
- *	- H.261
+ *	- \b H.261
  *		- only handled in passthrough mode in Asterisk, no codec module
  *		- \ref format_h261.c
- *	- H.263
+ *	- \b H.263
  *		- only handled in passthrough mode in Asterisk, no codec module
  *		- \ref format_h263.c
- *	- H.264
+ *	- \b H.264
  *		- only handled in passthrough mode in Asterisk, no codec module
  *		- \ref format_h264.c
+ *	- \b H.263+
+ *		- only handled in passthrough mode in Asterisk, no codec module
+ *
+ *	- \b MPGE4
+ *		- only handled in passthrough mode in Asterisk, no codec module
  *
  *	In protocols that use SDP, the Session Description Protocol, we negotiate
  * 	these attributes according to the SDP offer/answer model.
@@ -105,24 +110,52 @@
 /*! The h.264 profile level is the profile (eg 1.1 x 10) */
 typedef enum
 {
-	level_1   = 10, /* 0x0A */
-	level_1_1 = 11, /* 0x0B */
-	level_1_2 = 12, /* 0x0C */
-	level_1_3 = 13, /* 0x0D */
-	level_2   = 20, /* 0x14 */
-	level_2_1 = 21, /* 0x15 */
-	level_2_2 = 22, /* 0x16 */
-	level_3   = 30, /* 0x1E */
-	level_3_1 = 31, /* 0x1F */
-	level_3_2 = 32, /* 0x20 */
-	level_4   = 40, /* 0x28 */
-	level_4_1 = 41, /* 0x29 */
-	level_4_2 = 42, /* 0x2A */
-	level_5   = 50, /* 0x32 */
-	level_5_1 = 51, /* 0x33 */
+	level_1   = 10, /*!< 0x0A */
+	level_1_1 = 11, /*!< 0x0B */
+	level_1_2 = 12, /*!< 0x0C */
+	level_1_3 = 13, /*!< 0x0D */
+	level_2   = 20, /*!< 0x14 */
+	level_2_1 = 21, /*!< 0x15 */
+	level_2_2 = 22, /*!< 0x16 */
+	level_3   = 30, /*!< 0x1E */
+	level_3_1 = 31, /*!< 0x1F */
+	level_3_2 = 32, /*!< 0x20 */
+	level_4   = 40, /*!< 0x28 */
+	level_4_1 = 41, /*!< 0x29 */
+	level_4_2 = 42, /*!< 0x2A */
+	level_5   = 50, /*!< 0x32 */
+	level_5_1 = 51, /*!< 0x33 */
 } ast_h264_profile_level;
 
-/*!The following array defines the video sizes we know about */
+/*! \brief MPEG 4 video profile_and_level_indication as in table G-1 ISO 14496-2 */
+typedef enum
+{
+	sp_level_1 = 1, /*!< Simple profile level 1 */
+	sp_level_2 = 2, /*!< Simple profile level 2 */
+	sp_level_3 = 3, /*!< Simple profile level 3 */
+	ssp_level_1 = 0x11, /*!< Simple Scalable profile level 1 */
+	ssp_level_2 = 0x12, /*!< Simple Scalable profile level 2 */
+	cp_level_1 = 0x21, /*!< core profile level 1 */
+	cp_level_2 = 0x22, /*!< core profile level 2 */
+	mp_level_2 = 0x32, /*!< main profile level 2 */
+	mp_level_3 = 0x33, /*!< main profile level 3 */
+	mp_level_4 = 0x34, /*!< main profile level 4 */
+	bnp_level_2 = 0x42, /*!< N-bit profile level 2 */
+	stp_level_1 = 0x51, /*!< scalable texture profile level 1 */
+	sap_level_1 = 0x61, /*!< Simple face animation profile level 1*/
+	sap_level_2 = 0x62, /*!< Simple face animation profile level 2*/
+	fba_level_1 = 0x63, /*!< Simple FBA profile level 1 */
+	fba_level_2 = 0x64, /*!< Simple FBA profile level 2 */
+	batp_level_1 = 0x71, /*!< Basic Animated Texture Profile level 1 */
+	batp_level_2 = 0x72, /*!< Basic Animated Texture Profile level 1 */
+	hp_level_1 = 0x81,  /*!< Hybrid profile level 1 */
+	asp_level_1 = 0x91, /*!< Advanced simple profile level 1 */
+	asp_level_2 = 0x92, /*!< Advanced simple profile level 2 */
+	asp_level_3 = 0x93, /*!< Advanced simple profile level 3 */
+	asp_level_4 = 0x94, /*!< Advanced simple profile level 4 */
+} ast_mpeg4v_profile_level;
+
+/*! \brief The following array defines the video sizes we know about */
 struct videoSize {
 	char*         type;
 	unsigned int  num_mbs;
@@ -136,6 +169,8 @@
 struct ast_h2613_video_cap {
 	int           valid;                            /*!< 1 = This codec is specified, 0 = not specified */
 	unsigned int  annexes;                          /*!< Video annexes - stored as bitfield 2^(annex-ascii(A))*/
+	unsigned char profile;                          /*!< Video flags -- will only be used for h263+ */
+	unsigned char level;                            /*!< Profile level -- will only be used for h263+ */
 	unsigned char maxfr[MAX_VIDEO_SIZES];           /*!< Maximum framerate (framerate = 30/mpi)  */
 	unsigned int  maxbr;                            /*!< Maximum supported bitrate for this capability */
 };
@@ -160,8 +195,11 @@
 	unsigned int               maxvideobitrate; /*!< Max video bitrate */
 	struct ast_h2613_video_cap h261;            /*!< H261 video capabilities */
 	struct ast_h2613_video_cap h263;            /*!< H263 video capabilities */
+	struct ast_h2613_video_cap h263p;           /*!< H263+ video capabilities */
+	struct ast_h264_video_cap  mp4v;            /*!< MPEG4 video capabilities */
 	struct ast_h264_video_cap  h264;            /*!< H264 video capabilities */
 	unsigned char              t140;            /*!< T140 text capabilities */  
+	unsigned char              red;             /*!< RED text capabilities */  
 	struct ast_variable	   *x_settings;	    /*!< Settings outside of the specification received in SDP */
 };
 
@@ -173,7 +211,6 @@
  */
 int ast_set_capabilities(struct ast_channel *chan, struct ast_capabilities *chancaps);
 
-/*! \brief Allocate capability structure for video */
 struct ast_capabilities *ast_alloc_capabilities(void);
 
 void ast_dump_caps(struct ast_capabilities *caps);
@@ -186,6 +223,10 @@
 
 void ast_resolve_h264_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap);
 
+void ast_resolve_h263p_video_cap(struct ast_h2613_video_cap *dstcap, struct ast_h2613_video_cap *s1cap, struct ast_h2613_video_cap *s2cap);
+
+void ast_resolve_mp4v_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap);
+
 int ast_copy_capabilities(struct ast_capabilities *dstcap, struct ast_capabilities *srccap);
 
 int ast_resolve_capabilities(struct ast_capabilities *dst, struct ast_capabilities *s1caps, struct ast_capabilities *s2caps, int debug);
@@ -196,9 +237,13 @@
 
 int ast_get_int_from_capabilities(struct ast_capabilities *caps);
 
+int ast_get_negotiated_caps(struct ast_channel *chan, struct ast_capabilities *chancaps);
+
 int check_set_video_bitrates(struct ast_capabilities *caps, int debug);
 
 int parse_h2613_conf_line(const char *fmtstr, struct ast_h2613_video_cap *vidcap, unsigned int framerate);
+
+int parse_mp4v_conf_line(const char *fmtstr, struct ast_h264_video_cap *vidcap, int framerate);
 
 int parse_h264_conf_line(const char *fmtstr, struct ast_h264_video_cap *vidcap, int framerate);
 

Modified: team/oej/videocaps/include/asterisk/channel.h
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/include/asterisk/channel.h?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/include/asterisk/channel.h (original)
+++ team/oej/videocaps/include/asterisk/channel.h Wed Jan 30 15:27:30 2008
@@ -337,6 +337,9 @@
 
 	/*! \brief Set Channel Capabilities */
 	int (* const set_capabilities)(struct ast_channel *chan, struct ast_capabilities *chancaps);
+
+        /*! \brief Get Negociated Capabilities */
+        int (* const get_negotiated_caps)(struct ast_channel *chan, struct ast_capabilities *chancaps);
 
 	/*! \brief Retrieve base channel (agent and local) */
 	struct ast_channel* (* get_base_channel)(struct ast_channel *chan);

Modified: team/oej/videocaps/main/Makefile
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/main/Makefile?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/main/Makefile (original)
+++ team/oej/videocaps/main/Makefile Wed Jan 30 15:27:30 2008
@@ -30,7 +30,7 @@
 	cryptostub.o sha1.o http.o fixedjitterbuf.o abstract_jb.o \
 	strcompat.o threadstorage.o dial.o event.o adsistub.o audiohook.o \
 	astobj2.o hashtab.o global_datastores.o $(RESAMPLE_OBJS) version.o \
-	features.o
+	capability.o features.o
 
 # we need to link in the objects statically, not as a library, because
 # otherwise modules will not have them available if none of the static

Modified: team/oej/videocaps/main/capability.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/main/capability.c?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/main/capability.c (original)
+++ team/oej/videocaps/main/capability.c Wed Jan 30 15:27:30 2008
@@ -49,14 +49,17 @@
 struct ast_capabilities ast_default_caps = 
 {
 	0,
-	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},
+	{0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0},		/* Audio preference order */
 	DEFAULT_MAX_CALL_BITRATE,
 	DEFAULT_MAX_CALL_BITRATE,
-	{0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},	/* H.261 */
-	{0, 0, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},	/* H.263 */
-	{0, 0, 0x42, 0x0c, 0x80, 7128, 0, DEFAULT_MAX_CALL_BITRATE},	/* H.264 */
-	0,
-	NULL,	/* X-variables */
+	{0, 0, 0xFF, 0xFF, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},	/* H.261 */
+	{0, 0, 0xFF, 0xFF, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},	/* H.263 */
+	{0, 0, 0xFF, 0xFF, {0,0,30,0,0,30,0,0,0,0,0}, DEFAULT_MAX_CALL_BITRATE},	/* H.263+ */
+	{0, 0, 0xFF, 0xFF, 0x00, 7128, 0, DEFAULT_MAX_CALL_BITRATE},			/* MPEG4 Video */
+	{0, 0, 0xFF, 0xFF, 0x00, 7128, 0, DEFAULT_MAX_CALL_BITRATE},			/* H.264 */
+	0,										/* T140 */
+	0,										/* RED */
+	NULL,										/* X-variables */
 };	
 
 /*! \brief Allocate a capability structure 
@@ -79,9 +82,23 @@
 	return res;
 }
 
+/*! \brief called from channel.c:channel_make_compatible, to retrieve the peer prefered codecs */
+int ast_get_negotiated_caps(struct ast_channel *chan, struct ast_capabilities *chancaps)
+{
+	if (!chan)
+		return -1;
+
+	if (chan->tech->get_negotiated_caps)
+		chan->tech->get_negotiated_caps(chan, chancaps);
+
+	return 0;
+}
+
+
 void ast_dump_h2613_video_cap(struct ast_h2613_video_cap *vidcap)
 {
 	int i;
+	unsigned char comp=0xFF;
 	
 	if (vidcap->valid) {
 		ast_verbose("    MaxBR:      %dkbps\n", vidcap->maxbr/1000);
@@ -90,17 +107,39 @@
 				ast_verbose("    %-11s %1dfps\n", videoSizes[i].type, vidcap->maxfr[i]);
 		}
 		if (vidcap->annexes)
-			ast_verbose("    Annexes:    0x%08x\n",vidcap->annexes);
+			ast_verbose("    Annexes:    0x%08x\n", vidcap->annexes);
+		else
+			ast_verbose("    Annexes:    -\n");
+			
+		/* h263+ : */
+		if (vidcap->profile != comp)
+			ast_verbose("    Profile:    %02d\n", vidcap->profile);
+		else
+			ast_verbose("    Profile:    -\n");
+		if (vidcap->level != comp)
+			ast_verbose("    Level:      %02d\n", vidcap->level);
+		else
+			ast_verbose("    Level:      -\n");
+
 	} else
 		ast_verbose("\n");
 }
 
 void ast_dump_h264_video_cap(struct ast_h264_video_cap *vidcap)
 {
+	unsigned char comp=0xFF;
 	if (vidcap->valid) {
 		ast_verbose("    RTPnum:     %03d\n",vidcap->rtpnum);
-		ast_verbose("    Profile:    %02x\n",vidcap->profile);
-		ast_verbose("    Level:      %02x\n",vidcap->level);
+
+	if (vidcap->profile != comp)
+		ast_verbose("    Profile:    %02d\n", vidcap->profile);
+	else
+		ast_verbose("    Profile:    -\n");
+	if (vidcap->level != comp)
+		ast_verbose("    Level:      %02d\n", vidcap->level);
+	else
+		ast_verbose("    Level:      -\n");
+
 		ast_verbose("    Constraint: %02x\n",vidcap->constraint);
 		ast_verbose("    PMode       %d\n",  vidcap->packet_mode);
 		ast_verbose("    MaxBR:      %dkbps\n", vidcap->maxbr/1000);
@@ -109,6 +148,7 @@
 		ast_verbose("\n");
 }
 
+
 void ast_dump_caps(struct ast_capabilities *caps)
 {
 	ast_verbose("  Bitrates:\n    MaxCall %dkbps\n    MaxVideo %dkbps\n", caps->maxcallbitrate/1000,caps->maxvideobitrate/1000);
@@ -120,12 +160,25 @@
 		ast_verbose("  H263:\n");
 		ast_dump_h2613_video_cap(&caps->h263);
 	}
+
+	/* added for h263+ */
+	if (caps->h263p.valid) {
+		ast_verbose("  H263+:\n");
+		ast_dump_h2613_video_cap(&caps->h263p);
+	}
+
+	if (caps->mp4v.valid) {
+		ast_verbose("  MPEG4 Video:\n");
+		ast_dump_h264_video_cap(&caps->mp4v);	/* We should have an mp4 dump function */
+	}
 	if (caps->h264.valid) {
 		ast_verbose("  H264:\n");
 		ast_dump_h264_video_cap(&caps->h264);
 	}
-	/* if (caps->t140.valid) */
+	/*
+	if (caps->t140.valid)
 		ast_verbose("  T140\n");
+	*/
 	
 	ast_verbose("\n");
 }
@@ -162,11 +215,50 @@
 	
 	/* Resolve bitrates */
 	dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
-
-}
-
-/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap */
-/* Can be called with dst same as one of the src caps */
+}
+
+
+
+
+
+/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap
+ *  * Can be called with dst same as one of the src caps */
+void ast_resolve_h263p_video_cap(struct ast_h2613_video_cap *dstcap, struct ast_h2613_video_cap *s1cap, struct ast_h2613_video_cap *s2cap)
+{
+	int i;
+
+	/*... resolve valids */
+	if (s1cap->valid && s2cap->valid)
+		dstcap->valid = 1;
+	else {
+		dstcap->valid = 0;
+		memset(dstcap->maxfr, 0, sizeof(dstcap->maxfr[0]) * MAX_VIDEO_SIZES);
+		dstcap->maxbr = 0;
+		dstcap->profile = 0;
+		dstcap->level = 0;
+		return;
+	}
+
+	/* Use the lowest frame rate even if zero */
+	for (i = 0; i < MAX_VIDEO_SIZES; i++)
+		dstcap->maxfr[i] = MIN(s1cap->maxfr[i], s2cap->maxfr[i]);
+
+	/* Union of annexes */
+	dstcap->annexes = s1cap->annexes | s2cap->annexes;
+
+	/* Resolve bitrates */
+	dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
+
+	/* Added for h263+ */
+	/* Resolve profiles */
+	dstcap->profile = MIN(s1cap->profile, s2cap->profile);
+	/* Resolve levels */
+	dstcap->level = MIN(s1cap->level, s2cap->level);;
+}
+
+
+/*! \brief Finds the highest common capability between the two source caps and applies it to the destination cap 
+	Can be called with dst same as one of the src caps */
 void ast_resolve_h264_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap)
 {
 	/*... resolve valids */
@@ -182,13 +274,13 @@
 		dstcap->maxmbps = 0;
 		return;
 	}
-		
+	
 	/* Resolve profiles */
 	dstcap->profile = MIN(s1cap->profile, s2cap->profile);
 	/* Resolve levels */
 	dstcap->level = MIN(s1cap->level, s2cap->level);
 	/* Resolve constraints */
-	dstcap->constraint = MIN(s1cap->constraint, s2cap->constraint);
+	dstcap->constraint = s1cap->constraint | s2cap->constraint;
 	/* Resolve bitrates */
 	dstcap->maxbr = MIN(s1cap->maxbr, s2cap->maxbr);
 	
@@ -198,11 +290,33 @@
 		dstcap->rtpnum = s2cap->rtpnum;
 }
 
-/*! \brief  ast_resolve_capabilities: called when we need to have dst = MIN(s1cap, s2cap), or in set theory terms s1cap INTERSECT s2cap (s1 n s2) */
+void ast_resolve_mp4v_video_cap(struct ast_h264_video_cap *dstcap, struct ast_h264_video_cap *s1cap, struct ast_h264_video_cap *s2cap)
+{
+	/*... resolve valids*/
+	if (s1cap->valid && s2cap->valid)
+		dstcap->valid = 1;
+	else {
+		dstcap->valid = 0;
+		dstcap->rtpnum = 0;
+		dstcap->profile = 0;
+		dstcap->constraint = 0;
+		dstcap->level = 0;
+		dstcap->maxbr = 0;
+		dstcap->maxmbps = 0;
+		return;
+	}
+
+	/* Resolve profiles */
+	dstcap->profile = MIN(s1cap->profile, s2cap->profile);
+	/* Resolve levels */
+	dstcap->level = MIN(s1cap->level, s2cap->level);
+}
+
+/*! \brief cClled when we need to have dst = MIN(s1cap, s2cap), or in set theory terms s1cap INTERSECT s2cap (s1 n s2) */
 int ast_resolve_capabilities(struct ast_capabilities *dst, struct ast_capabilities *s1caps, struct ast_capabilities *s2caps, int debug)
 {
 	int res = 0;
-
+	
 	if (debug) {
 		ast_verbose("\nResolve: Input Caps1:\n");
 		ast_dump_caps(s1caps);
@@ -214,6 +328,8 @@
 	dst->maxvideobitrate = MIN(s1caps->maxvideobitrate, s2caps->maxvideobitrate);
 	ast_resolve_h2613_video_cap(&dst->h261, &s1caps->h261, &s2caps->h261);
 	ast_resolve_h2613_video_cap(&dst->h263, &s1caps->h263, &s2caps->h263);
+	ast_resolve_h263p_video_cap(&dst->h263p, &s1caps->h263p, &s2caps->h263p);
+	ast_resolve_mp4v_video_cap(&dst->mp4v, &s1caps->mp4v, &s2caps->mp4v);
 	ast_resolve_h264_video_cap(&dst->h264, &s1caps->h264, &s2caps->h264);
 	
 	if (debug) {
@@ -224,17 +340,19 @@
 	return res;
 }
 
-/*! \brief  ast_set_capabilities_from_int: called when we need to make sure the complex caps are inline with old integer caps */
+/*! \brief called when we need to make sure the complex caps are inline with old integer caps */
 int ast_set_capabilities_from_int(struct ast_capabilities *caps, int simplecap)
 {
 	caps->h261.valid = ((simplecap & AST_FORMAT_H261) == AST_FORMAT_H261) ? 1 : 0;
 	caps->h263.valid = ((simplecap & AST_FORMAT_H263) == AST_FORMAT_H263) ? 1 : 0;
+	caps->h263p.valid = ((simplecap & AST_FORMAT_H263_PLUS) == AST_FORMAT_H263_PLUS) ? 1 : 0;
 	caps->h264.valid = ((simplecap & AST_FORMAT_H264) == AST_FORMAT_H264) ? 1 : 0;
+	caps->mp4v.valid = ((simplecap & AST_FORMAT_MP4_VIDEO) == AST_FORMAT_MP4_VIDEO) ? 1 : 0;
 	
 	return 0;
 } 
 
-/*! \brief  ast_set_capabilities_from_int: called when we need to make sure the complex caps are inline with old integer caps */
+/*! \brief Called when we need to make sure the complex caps are inline with old integer caps */
 int ast_get_int_from_capabilities(struct ast_capabilities *caps)
 {
 	int res=0;
@@ -245,8 +363,14 @@
 	if (caps->h263.valid)
 		res |= AST_FORMAT_H263;
 
+ 	if (caps->h263p.valid)
+		res |= AST_FORMAT_H263_PLUS;
+
 	if (caps->h264.valid)
 		res |= AST_FORMAT_H264;
+
+	if (caps->mp4v.valid)
+		res |= AST_FORMAT_MP4_VIDEO;
 
 	return 0;
 } 
@@ -262,7 +386,7 @@
 	return 0;
 }
 
-/*! \brief Checks all the video bitrates to make sure they conform to the following:
+/* Checks all the video bitrates to make sure they conform to the following:
    enforce maxcallbitrate >= maxvideobitrate >= maxbr
 	 This will be called when any bitrates can be set (incoming call, reload etc).
 	 The maxcallbitrate will override everything
@@ -274,12 +398,13 @@
 	int maxvbr  = caps->maxvideobitrate;
 	int maxh261 = caps->h261.valid ? caps->h261.maxbr : 0;
 	int maxh263 = caps->h263.valid ? caps->h263.maxbr : 0;
+	int maxh263p = caps->h263p.valid ? caps->h263p.maxbr : 0;
 	int maxh264 = caps->h264.valid ? caps->h264.maxbr : 0;
 	int maxmedia = MAX(maxh261, MAX(maxh263, maxh264));
 
 	if(debug) {	
-		ast_verbose ("CHECK SET BITRATES (IN): ct=%d, vbr=%d, h261=%d, h263=%d, h264=%d, maxmedia=%d\n",
-		  maxctbr, maxvbr, maxh261, maxh263, maxh264, maxmedia);
+		ast_verbose ("CHECK SET BITRATES (IN): ct=%d, vbr=%d, h261=%d, h263=%d, h263p=%d, h264=%d, maxmedia=%d\n",
+		  maxctbr, maxvbr, maxh261, maxh263, maxh263p, maxh264, maxmedia);
 	}
 
 	/* Make sure ct and vbr are set to something sensible */
@@ -306,18 +431,23 @@
 		maxh264 = maxvbr;
 	if (maxh263 > maxvbr)
 		maxh263 = maxvbr;
+
+ 	if (maxh263p > maxvbr)
+		maxh263p = maxvbr;
+
 	if (maxh261 > maxvbr)
 		maxh261 = maxvbr;
 	
 	caps->h264.maxbr = maxh264;
 	caps->h263.maxbr = maxh263;
+	caps->h263p.maxbr = maxh263p;
 	caps->h261.maxbr = maxh261;
 	caps->maxvideobitrate = maxvbr;
 	caps->maxcallbitrate = maxctbr;
 
-	if(debug) {
+	if(debug) {/*! \note: to check for H263+... */
 		maxmedia = MAX(maxh261, MAX(maxh263, maxh264));
-  	
+ 	
 		ast_verbose ("CHECK SET BITRATES (OUT): ct=%d, vbr=%d, h261=%d, h263=%d, h264=%d, maxmedia=%d\n",
 		  maxctbr, maxvbr, maxh261, maxh263, maxh264, maxmedia);
 	}
@@ -325,9 +455,7 @@
 	return 0;
 }
 
-/*! Parse configuration file item for H.261/H.263 
-	\note syntax is as follows:
-		<Free space to fill in a syntax >
+/*! \brief Parse sdp description file file item for H.261/H.263 
  */
 int parse_h2613_conf_line(const char *fmtstr, struct ast_h2613_video_cap *vidcap, unsigned int framerate)
 {
@@ -337,12 +465,25 @@
 	int i;
 	unsigned int tmp;
 	int found=0;
+	int profile = 0;
+	int level = 0;
 	
 	memset(vidcap, 0, sizeof(struct ast_h2613_video_cap));
 	
+	/* Initialize 'profile' and 'level' as 'Not Defined' */
+	vidcap->profile = 0xFF;
+	vidcap->level = 0xFF;
+
 	parse = ast_strdupa(fmtstr);
 	/* Get the fmtp: and payload type out of the way */
 	for ((loop_str = strsep(&parse, sep)); loop_str; (loop_str = strsep(&parse, sep)) != NULL) {
+
+		/* H263+ related */
+	       if (loop_str[0] == '\0') {
+			loop_str++;
+			continue;
+		}
+
 		if((equals = strchr(loop_str, '='))==NULL)
 			return -1;
 		found = 0;
@@ -356,17 +497,36 @@
 				/* ast_verbose("MaxBR=%d\n", vidcap->maxbr); */
 			} else
 				ast_verbose("Failed to parse maxbr in process_h261_h261_fmtp()\n");
+		
+		/* Process for H263+ ----------------- */
+		} else if (!strncasecmp(loop_str, "profile", len)) {
+			if(sscanf(value_str, "%02x", &profile)){
+				found = 1;
+				vidcap->valid = 1;
+				vidcap->profile = profile;
+			} else
+				ast_verbose("----- Failed to parse profile in process_h2613_fmtp()!\n");
+		} else if (!strncasecmp(loop_str, "level", len)) {
+			if(sscanf(value_str, "%02x", &level)){
+				found = 1;
+				vidcap->valid = 1;
+				vidcap->level = level;
+			} else
+				ast_verbose("----- Failed to parse level in process_h2613_fmtp()!\n");
 		} else if (len == 1 && loop_str[0] >= 'A' && loop_str[0] <= 'Z') { /* this is an annex */
 			vidcap->annexes |= (1 << (loop_str[0] - 'A'));
 			found = 1;
-			ast_verbose("Found annex %c, we now have %08x\n", loop_str[0], vidcap->annexes);
+			ast_verbose("----- Found annex %c, we now have %08x\n", loop_str[0], vidcap->annexes);
+		/* TO BE DONE : get the annex value, e.g.: */
+		/*'K', 'N' and 'P'  could be set from '1' to '4' */
+		/* => see "rfc4629 - RTP Payload Format for ITU-T Rec. H.263 Video" */
+
 		} else {  /* Check video sizes */
 			for (i = 0; i < MAX_VIDEO_SIZES; i++) {
 				if (strlen(videoSizes[i].type) == len && !strncasecmp(loop_str, videoSizes[i].type, len)) {
 					if (sscanf(value_str, "%d", &tmp)){
 						found = 1;
-						/* vidcap->maxfr[i] = framerate < (30 / tmp) ? framerate : (30 /tmp); */
-						vidcap->maxfr[i] = (tmp > 30) ? 30 : (tmp < 0) ? 0 : tmp; 
+						vidcap->maxfr[i] = framerate < (30 / tmp) ? framerate : (30 /tmp);
 						vidcap->valid = 1;
 					}
 					/* ast_verbose("%s->FR=%d, len=%d, string=%s\n", videoSizes[i].type, vidcap->maxfr[i], len, loop_str); */
@@ -374,7 +534,7 @@
 			}
 		}
 		if (!found)
-			ast_verbose("Unable to parse %s in fmtp\n", loop_str);
+			ast_verbose("----- Unable to parse %s in fmtp\n", loop_str);
 	}
 	
 	if (vidcap->valid && vidcap->maxbr)
@@ -399,12 +559,10 @@
 	int level = 0;
 	int constraint = 0;
 	int packetmode = 0;
-	int rtpnum=0;
 	
 	/* "a=fmtp:%d profile-level-id=42800C; packetization-mode=0; max-br=384; max-mbps=7128\r\n" */
 	
 	memcpy(myVideoSizes, videoSizes, sizeof(myVideoSizes));
-	
 	parse = ast_strdupa(fmtstr);
 	
 	/* Get the fmtp: and payload type out of the way */
@@ -423,30 +581,28 @@
 			if(sscanf(value_str, "%d", &maxbr))
 				found = 1;
 			else
-				ast_verbose("Failed to parse max-br in process_h264_fmtp()\n");
+				ast_verbose("----- Failed to parse max-br in process_h264_fmtp()!\n");
 		} else if (!strncasecmp(loop_str, "max-mbps", len)) {
 			if(sscanf(value_str, "%d", &maxmbps))
 				found = 1;
 			else
-				ast_verbose("Failed to parse max-mbps in process_h264_fmtp()\n");
+				ast_verbose("----- Failed to parse max-mbps in process_h264_fmtp()!\n");
 		} else if (!strncasecmp(loop_str, "profile-level-id", len)) {
 			if(sscanf(value_str, "%02x%02x%02x", &profile, &constraint, &level))
 				found = 1;
 			else
-				ast_verbose("Failed to parse profile-level-id in process_h264_fmtp()\n");
+				ast_verbose("----- Failed to parse profile-level-id in process_h264_fmtp()!\n");
 		} else if (!strncasecmp(loop_str, "packetization-mode", len)) {
 			if(sscanf(value_str, "%d", &packetmode))
 				found = 1;
 			else
-				ast_verbose("Failed to parse packetization-mode in process_h264_fmtp()\n");
-		} else if (!strncasecmp(loop_str, "rtpnum", len)) {
-			if(sscanf(value_str, "%d", &rtpnum))
-				found = 1;
-			else
-				ast_verbose("Failed to parse rtpnum in process_h264_fmtp()\n");
+				ast_verbose("----- Failed to parse packetization-mode in process_h264_fmtp()!\n");
+		} else if (!strncasecmp(loop_str, "sprop-parameter-sets", len)){
+			/*! \todo XXX TO BE DONE, see "rfc3984 - RTP Payload Format for H.264 Video" */
 		}
+
 		if (!found)
-			ast_verbose("Unable to parse %s in fmtp\n", loop_str);
+			ast_verbose("----- Unable to parse %s in fmtp\n", loop_str);
 	}
 
 	/* Work out picture sizes from supplied level */
@@ -493,7 +649,94 @@
 	vidcap->level = level;
 	vidcap->constraint = constraint;
 	vidcap->valid = 1;
-	vidcap->rtpnum = rtpnum;
+	/* vidcap->rtpnum = rtpnum; */
 	
 	return 0;
 }
+
+int parse_mp4v_conf_line(const char *fmtstr, struct ast_h264_video_cap *vidcap, int framerate)
+{
+	char *parse, *loop_str, *equals, *value_str;
+	char *sep = " ;:/,";
+	int len;
+	struct videoSize myVideoSizes[MAX_VIDEO_SIZES];
+	int found=0;
+	int level = 0;
+	int profile_level = 0;
+	int profile = 0;
+	int low_mask = 15; 	//Level
+	int high_mask = 240; 	//Profile
+
+	/* "a=fmtp:%d profile-level-id=34; config=08462A8CE6D" */
+	memcpy(myVideoSizes, videoSizes, sizeof(myVideoSizes));
+	
+	parse = ast_strdupa(fmtstr);
+
+	loop_str = strsep(&parse, sep);
+
+	for (; loop_str != NULL; loop_str = strsep(&parse, sep) ) {
+		if (loop_str[0] == '\0') {
+			loop_str++;
+			continue;
+		}
+		if((equals = strchr(loop_str, '='))==NULL)
+			return -1;
+		found = 0;
+		len = equals - loop_str;
+		value_str = loop_str+len+1;
+		/* Now check other parameters than can appear in a video fmtp */
+		if (!strncasecmp(loop_str, "profile-level-id", len)) {
+			if(sscanf(value_str, "%d", &profile_level)){
+				level = low_mask&profile_level;
+				profile = (high_mask&profile_level)>>4;
+				found = 1;
+			} else
+				ast_verbose("----- Failed to parse profile-level-id in process_mp4_fmtp()\n");
+   		} else if (!strncasecmp(loop_str, "config", len)){
+			/*! \todo XXX TO BE DONE, see "rfc3016 - RTP Payload Format for MPEG-4 AudioVisual Streams" */
+		}
+	}
+
+	/* Work out picture sizes from supplied level */
+	switch (level) {
+	case sp_level_1   :
+		/*! \todo Figure out these picture sizes */
+		/*level_maxbr =   64000; */
+		/*level_maxmbps = 1485; */
+		break;
+	case sp_level_2 :
+		/*level_maxbr =   64000; */
+		/*level_maxmbps = 3000; */
+		break;
+	case sp_level_3 :
+		/*level_maxbr =  128000; */
+		/*level_maxmbps = 6000; */
+		break;
+	case asp_level_1:
+		/*level_maxbr =  384000; */
+		/*level_maxmbps = 11880; */
+		break;
+	case asp_level_2:
+		/*level_maxbr =  768000; */
+		/*level_maxmbps = 11880; */
+		break;
+	case asp_level_3:
+		/*level_maxbr =  768000; */
+		/*level_maxmbps = 11880; */
+		break;
+	case asp_level_4:
+		/*level_maxbr =  768000; */
+		/*level_maxmbps = 11880; */
+		break;
+	default:
+		/*level_maxbr = 2000000; */
+		/*level_maxmbps = 11880; */
+		break;
+	}
+
+
+	vidcap->profile = profile;
+	vidcap->level = level;
+
+	return 0;
+}

Modified: team/oej/videocaps/main/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/videocaps/main/channel.c?view=diff&rev=101343&r1=101342&r2=101343
==============================================================================
--- team/oej/videocaps/main/channel.c (original)
+++ team/oej/videocaps/main/channel.c Wed Jan 30 15:27:30 2008
@@ -3329,32 +3329,78 @@
 	return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
 }
 
-/*! \brief Set up translation from one channel to another */
-static int ast_channel_make_compatible_helper(struct ast_channel *from, struct ast_channel *to)
-{
-	int src;
-	int dst;
-
-	if (from->readformat == to->writeformat && from->writeformat == to->readformat) {
-		/* Already compatible!  Moving on ... */
-		return 0;
-	}
-
-	/* Set up translation from the 'from' channel to the 'to' channel */
-	src = from->nativeformats & AST_FORMAT_AUDIO_MASK;
-	dst = to->nativeformats & AST_FORMAT_AUDIO_MASK;
-	if (ast_translator_best_choice(&dst, &src) < 0) {
-		ast_log(LOG_WARNING, "No path to translate from %s(0x%08x) to %s(0x%08x)\n", from->name, src, to->name, dst);
-		return -1;
-	}
+static int negotiate_formats(const char *chan_name, int *src, const char *peer_name, int *dst)
+{
+        int asrc, vsrc, tsrc;
+        int adst, vdst, tdst;
+
+        asrc = *src & AST_FORMAT_AUDIO_MASK;
+        adst = *dst & AST_FORMAT_AUDIO_MASK;
+
+        vsrc = *src & AST_FORMAT_VIDEO_MASK;
+        vdst = *dst & AST_FORMAT_VIDEO_MASK;
+
+        tsrc = *src & AST_FORMAT_TEXT_MASK;
+        tdst = *dst & AST_FORMAT_TEXT_MASK;
+
+        if (ast_translator_best_choice(&adst, &asrc) < 0) {
+		ast_log(LOG_WARNING, "No path to translate AUDIO from chan=%s (%08x) to peer=%s (%08x)\n", chan_name, asrc, peer_name, adst);
+                return -1;
+        }
 
 	/* if the best path is not 'pass through', then
 	   transcoding is needed; if desired, force transcode path
 	   to use SLINEAR between channels, but only if there is
 	   no direct conversion available */
-	if ((src != dst) && ast_opt_transcode_via_slin &&
-	    (ast_translate_path_steps(dst, src) != 1))
-		dst = AST_FORMAT_SLINEAR;
+        if ((asrc != adst) && ast_opt_transcode_via_slin && (ast_translate_path_steps(adst, asrc) != 1)) {

[... 79 lines stripped ...]



More information about the asterisk-commits mailing list