[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