[asterisk-commits] rizzo: branch rizzo/video_v2 r85092 - /team/rizzo/video_v2/channels/

SVN commits to the Asterisk project asterisk-commits at lists.digium.com
Tue Oct 9 09:23:20 CDT 2007


Author: rizzo
Date: Tue Oct  9 09:23:19 2007
New Revision: 85092

URL: http://svn.digium.com/view/asterisk?view=rev&rev=85092
Log:
fix the h263 encapsulation after reading the h263 specs.


Modified:
    team/rizzo/video_v2/channels/console_video.c

Modified: team/rizzo/video_v2/channels/console_video.c
URL: http://svn.digium.com/view/asterisk/team/rizzo/video_v2/channels/console_video.c?view=diff&rev=85092&r1=85091&r2=85092
==============================================================================
--- team/rizzo/video_v2/channels/console_video.c (original)
+++ team/rizzo/video_v2/channels/console_video.c Tue Oct  9 09:23:19 2007
@@ -605,69 +605,99 @@
  *
  * Mode B and mode C description omitted.
  *
- * Note - Group Of Blocks (GOB) are byte-aligned, they start with
+ * An RTP frame can start with a PSC 0000 0000 0000 0000 1000 0
+ * or with a GBSC, which also has the first 17 bits as a PSC.
+ * Note - PSC are byte-aligned, GOB not necessarily. PSC start with
  *	PSC:22 0000 0000 0000 0000 1000 00 	picture start code
  *	TR:8   .... ....			temporal reference
  *      PTYPE:13 or more 			ptype...
  * If we don't fragment a GOB SBIT and EBIT = 0.
  * reference, 8 bit) 
  * 
+ * The assumption below is that we start with a PSC.
  */
 static struct ast_frame *h263_encap(struct video_out_desc *out,
 		struct ast_frame **tail)
 {
-	uint8_t *nextgob = NULL;
 	uint8_t *d = out->enc_out.data;
-	uint8_t *end = d + out->enc_out.used;
+	int start = 0, i, len = out->enc_out.used;
 	struct ast_frame *f, *cur = NULL, *first = NULL;
 	const int pheader_len = 4;	/* Use RFC-2190 Mode A */
-
-	for (; d != end; d = nextgob) {
-		uint8_t *data = NULL;
-		int l;
-		uint16_t test = 0xffff;
-
-		/* XXX double check this.
-		 * look for two consecutive 0s and at least 5 bytes
-		 * of data. On exit, nextgob points two bytes before
-		 * the 00 marker, or right at the end of data.
+	uint8_t h263_hdr[12];	/* worst case, room for a type c header */
+	uint8_t *h = h263_hdr;	/* shorthand */
+
+#define H263_MIN_LEN	6
+	if (len < H263_MIN_LEN)	/* unreasonably small */
+		return NULL;
+
+	bzero(h263_hdr, sizeof(h263_hdr));
+	/* Now set the header bytes. Only type A by now,
+	 * and h[0] = h[2] = h[3] = 0 by default.
+	 * PTYPE starts 30 bits in the picture, so the first useful
+	 * bit for us is bit 36 i.e. within d[4] (0 is the msbit).
+	 * SRC = d[4] & 0x1c goes into data[1] & 0xe0
+	 * I   = d[4] & 0x02 goes into data[1] & 0x10
+	 * U   = d[4] & 0x01 goes into data[1] & 0x08
+	 * S   = d[5] & 0x80 goes into data[1] & 0x04
+	 * A   = d[5] & 0x40 goes into data[1] & 0x02
+	 * R   = 0           goes into data[1] & 0x01
+	 * Optimizing it, we have
+	 */
+	h[1] = ( (d[4] & 0x1f) << 3 ) |	/* SRC, I, U */
+		( (d[5] & 0xc0) >> 5 );		/* S, A, R */
+
+	/* now look for the next PSC or GOB header. First try to hit
+	 * a '0' byte then look around for the 0000 0000 0000 0000 1 pattern
+	 * which is both in the PSC and the GBSC.
+	 */
+	for (i = H263_MIN_LEN, start = 0; start < len; start = i) {
+		for (; i < len ; i++) {
+			uint8_t x, rpos, lpos;
+			if (d[i] != 0)		/* cannot be in a GBSC */
+				continue;
+			if (i > len - 1)
+				break;
+			x = d[i+1];
+			if (x == 0)	/* next is equally good */
+				continue;
+			/* see if around us we can make 16 '0' bits for the GBSC.
+			 * Look for the first bit set on the right, and then
+			 * see if we have enough 0 on the left.
+			 * We are guaranteed to end before rpos == 0
+			 */
+			for (rpos = 0x80; rpos; rpos >>= 1)
+				if (x & rpos)	/* found the '1' bit in GBSC */
+					break;
+			x = d[i-1];		/* now look behind */
+			for (lpos = rpos; lpos ; lpos >>= 1)
+				if (x & lpos)	/* too early, not a GBSC */
+					break;
+			if (lpos)		/* as i said... */
+				continue;
+			/* now we have a GBSC starting somewhere in d[i-1],
+			 * but it might be not byte-aligned
+			 */
+			if (rpos == 0x80) {	/* lucky case */
+				i = i - 1;
+			} else {	/* XXX to be completed */
+				ast_log(LOG_WARNING, "unaligned GBSC 0x%x\n",
+					rpos);
+			}
+			break;
+		}
+		/* This frame is up to offset i (not inclusive).
+		 * We do not split it yet even if larger than MTU.
 		 */
-		for (nextgob = d; nextgob < end; nextgob++) {
-			test = (test << 8) | (*nextgob);
-			if (test == 0 && nextgob - d > 4) {
-				nextgob -= 3;
-				break;
-			}
-		}
-
-		/* We cannot split the block even if larger than MTU */
-		l = nextgob - d;
-
-		f = create_video_frame(d, d+l, AST_FORMAT_H263,
+
+		f = create_video_frame(d + start, d+i, AST_FORMAT_H263,
 				pheader_len, cur);
 
 		if (!f)
 			break;
-		data = f->data;
-
-		/* Now set the header bytes */
-		data[0] =  0;	/* this is easy, F:1 P:1 SBIT:3 EBIT:3 */
-		/* ptype starts 30 bits in the GOB, so the first useful
-		 * bit for us is bit 36 i.e. within d[4] (0 is the msbit).
-		 * SRC = d[4] & 0x1c goes into data[1] & 0xe0
-		 * I   = d[4] & 0x02 goes into data[1] & 0x10
-		 * U   = d[4] & 0x01 goes into data[1] & 0x08
-		 * S   = d[5] & 0x80 goes into data[1] & 0x04
-		 * A   = d[5] & 0x40 goes into data[1] & 0x02
-		 * R   = 0           goes into data[1] & 0x01
-		 * Optimizing it, we have
+		bcopy(h, f->data, 4);	/* copy the h263 header */
+		/* XXX to do: if not aligned, fix sbit and ebit,
+		 * then move i back by 1 for the next frame
 		 */
-		data[1] =  	/* SRC:3 I:1 U:1 S:1 A:1 R:1 */
-			( (d[4] & 0x1f) << 3 ) |	/* SRC, I, U */
-			( (d[5] & 0xc0) >> 5 );		/* S, A, R */
-		/* in mode A, all other fields are 0 */
-		data[2] = 0;
-		data[3] = 0;
 		if (!cur)
 			first = f;
 		cur = f;
@@ -723,9 +753,8 @@
 	uint8_t *d = out->enc_out.data;
 	int len = out->enc_out.used;
 	uint8_t *end = d+len;
-	int l;
-
-	for (; len > 0; len -= l, d +=l) {
+
+	while (d < end) {
 		uint8_t *iter;
 		uint8_t *data;
 		for (iter = d+2; iter < end-2; iter++)
@@ -734,8 +763,8 @@
 
 		if (iter == end-2)
 			iter = end;
-		l = iter-d;
 		f = create_video_frame(d, iter, AST_FORMAT_H261, 4, cur);
+		d = iter;
 		if (!f)
 			break;
 




More information about the asterisk-commits mailing list