[asterisk-commits] rizzo: branch rizzo/video_v2 r82585 - /team/rizzo/video_v2/channels/
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Sep 17 10:28:45 CDT 2007
Author: rizzo
Date: Mon Sep 17 10:28:44 2007
New Revision: 82585
URL: http://svn.digium.com/view/asterisk?view=rev&rev=82585
Log:
more cleanup of this code, while still struggling with
properly segmenting frames
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=82585&r1=82584&r2=82585
==============================================================================
--- team/rizzo/video_v2/channels/console_video.c (original)
+++ team/rizzo/video_v2/channels/console_video.c Mon Sep 17 10:28:44 2007
@@ -128,7 +128,7 @@
AVCodecParserContext *parser;
int completed; /* probably unnecessary */
struct dbuf_t buf;
- int lastrxframe;
+ uint16_t next_seq; /* must be 16 bit */
int discard;
struct timeval ts;
int received;
@@ -397,7 +397,7 @@
v->parser = NULL;
v->buf.data = NULL;
v->completed = 0;
- v->lastrxframe = -1;
+ v->discard = 1;
v->ts = ast_tvnow();
codec = map_video_format(format);
@@ -638,19 +638,19 @@
int PLEN;
int P;
- if(data == NULL)
- return NULL;
- if(*len < 2)
- return NULL;
-
+ if (*len < 2) {
+ ast_log(LOG_WARNING, "invalid framesize %d\n", *len);
+ *len = 0;
+ return data;
+ }
PLEN = rfc2429_get_PLEN(data);
P = rfc2429_get_P(data);
- if(PLEN > 0) {
+ if (PLEN > 0) {
data += PLEN;
(*len) -= PLEN;
}
- if(P)
+ if (P)
data[0] = data[1] = 0;
else {
data += 2;
@@ -820,21 +820,14 @@
uint8_t *data;
int len;
struct video_desc *env = get_video_desc(chan);
- struct timeval now = ast_tvnow();
- int i;
+ struct video_in_desc *v = &env->in;
if(!env->initialized) {
ast_log(LOG_WARNING, "here env should be already initialized\n");
return -1; /* error */
}
- i = ast_tvdiff_ms(now, env->in.ts);
- if (i > 1000) {
- //ast_log(LOG_WARNING, "received %d video frames in %d ms\n", env->in.received, i);
- env->in.received = 0;
- env->in.ts = now;
- }
- env->in.received++;
+ v->received++;
#if defined(DROP_PACKETS) && DROP_PACKETS > 0
/*
* Fragment of code to simulate lost/delayed packets
@@ -844,64 +837,78 @@
return 0;
}
#endif
+ if (v->discard) {
+ ast_log(LOG_WARNING, "discard mode, drop frame %d\n", f->seqno);
+ /*
+ * In discard mode, drop packets until we find one with
+ * the RTP marker set (which is the end of frame).
+ * XXX note that the RTP marker flag is sent as the LSB of the
+ * subclass. This is slightly annoying as it goes to overwrite
+ * the payload type entry.
+ */
+ if (f->subclass & 0x01) {
+ v->buf.used = 0;
+ v->next_seq = f->seqno + 1; /* wrap at 16 bit */
+ v->discard = 0;
+ ast_log(LOG_WARNING, "out of discard mode, frame %d\n", f->seqno);
+ }
+ return 0;
+ }
+
/*
- * If there is the discard flag, every packet must be discarded.
- * When a marked packet arrive we can restart the decoding.
- * XXX note that the RTP marker flag is sent as the LSB of the
- * subclass. This is slightly annoying as it goes to overwrite
- * the payload type entry.
+ * Only in-order fragments will be accepted. Remember seqno
+ * has 16 bit so there is wraparound. Also, ideally we could
+ * accept a bit of reordering, but at the moment wr don't.
*/
- if(env->in.discard) {
- if(f->subclass & 0x01) {
- free(env->in.buf.data);
- env->in.buf.data = NULL;
- env->in.buf.used = 0;
- env->in.lastrxframe = f->seqno;
- env->in.discard = 0;
- ast_log(LOG_WARNING, "out of discard mode, frame %d\n", f->seqno);
- }
- ast_log(LOG_WARNING, "discard mode, drop frame %d\n", f->seqno);
+ if (v->next_seq != f->seqno) {
+ ast_log(LOG_WARNING, "discarding frame out of order, %d %d\n",
+ v->next_seq, f->seqno);
+ v->discard = 1;
return 0;
}
-
- /*
- * Only ordered fragment will be accepted.
- * We can handle the circular seqno with the following operation
- * (seqno is a 16 bits number)
- */
- if((env->in.lastrxframe+1)%0x10000 != f->seqno && env->in.lastrxframe != -1) {
- ast_log(LOG_WARNING, "discarding frame out of order, %d %d\n",
- env->in.lastrxframe, f->seqno);
- env->in.discard = 1;
+ v->next_seq++;
+
+ if (f->data == NULL || f->datalen < 2) {
+ ast_log(LOG_WARNING, "empty video frame, discard\n");
return 0;
}
-
len = f->datalen;
ast_log(LOG_WARNING, "received video frame %d size %d\n", f->seqno, f->datalen);
data = pre_process_data(f->data, &len);
+ if (len < 1 || len > 128*1024) {
+ ast_log(LOG_WARNING, "--- huge frame %d\n", len);
+ v->discard = 1;
+ return 0;
+ }
/* allocate buffer as we see fit. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE
* and a 0 as a buffer terminator to prevent trouble.
*/
- if(env->in.buf.data == NULL) {
- env->in.buf.size = len + FF_INPUT_BUFFER_PADDING_SIZE;
- env->in.buf.used = 0;
- env->in.buf.data = malloc(len);
- } else if (env->in.buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE> env->in.buf.size) {
- env->in.buf.size = env->in.buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE;
- env->in.buf.data = realloc(env->in.buf.data, env->in.buf.size);
- }
- memcpy(env->in.buf.data+env->in.buf.used, data, len);
- env->in.buf.used += len;
- env->in.buf.data[env->in.buf.used] = '\0';
- if(f->subclass & 0x01) // RTP Marker
- if(decode_video(&env->in)) {
+ if (v->buf.data == NULL) {
+ v->buf.size = len + FF_INPUT_BUFFER_PADDING_SIZE;
+ v->buf.used = 0;
+ v->buf.data = ast_malloc(len);
+ } else if (v->buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE> v->buf.size) {
+ v->buf.size = v->buf.used + len + FF_INPUT_BUFFER_PADDING_SIZE;
+ v->buf.data = ast_realloc(v->buf.data, v->buf.size);
+ }
+ if (v->buf.data == NULL) {
+ ast_log(LOG_WARNING, "alloc failure for %d, discard\n",
+ v->buf.size);
+ v->discard = 1;
+ return 0;
+ }
+ memcpy(v->buf.data + v->buf.used, data, len);
+ v->buf.used += len;
+ v->buf.data[v->buf.used] = '\0';
+ v->buf.data[v->buf.used+1] = '\0'; /* just in case... */
+ if (f->subclass & 0x01) { // RTP Marker
+ if (decode_video(v)) {
show_frame(env, 0);
- env->in.completed = 0;
- env->in.buf.used = 0;
- }
- env->in.lastrxframe = f->seqno;
-
+ v->completed = 0;
+ v->buf.used = 0;
+ }
+ }
return 0;
}
@@ -920,6 +927,7 @@
uint8_t *start = out->decbuf.data;
int have_psc = 0; /* did we skip 2 bytes for this frame ? */
int l; /* size of the current fragment */
+ l = len;
for (;len > 0; start += l, len -= l) {
/* First try to split on a psc. If not, create an artificial break */
@@ -942,19 +950,27 @@
}
#endif
/* temporary - assume we have psc, drop first 2 bytes, send one large packet */
- have_psc = 1;
- start += 2;
- l = len - 2;
ast_log(LOG_WARNING, "len %d\n", l);
f = ast_calloc(1, sizeof(*f));
data = ast_calloc(1, l+2);
+ if (l < 1 || l > 128*1024 || f == NULL || data == NULL) {
+ ast_log(LOG_WARNING, "--- frame error f %p d %p l %d\n",
+ f, data, l);
+ break;
+ }
f->mallocd = AST_MALLOCD_DATA | AST_MALLOCD_HDR;
-
- data[0] = data[1] = 0; // P == 0
- if (have_psc)
+ f->data = data;
+
+ if (data[0] == 0 && data[1] == 0) { /* a psc */
+ memcpy(data, start, l);
data[0] |= 0x04; // P == 1
- memcpy(data+2, start, l);
+ f->datalen = l;
+ } else {
+ data[0] = data[1] = 0; // P == 0
+ memcpy(data + 2, start, l);
+ f->datalen = l + 2;
+ }
f->has_timing_info = 1;
f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
@@ -968,8 +984,6 @@
f->delivery.tv_sec = 0;
f->delivery.tv_usec = 0;
f->seqno = ++(out->lasttxframe);
- f->datalen = l + 2;
- f->data = data;
AST_LIST_NEXT(f, frame_list) = NULL;
if (cur)
@@ -983,7 +997,7 @@
if (cur)
cur->subclass |= 1; // RTP Marker
- ast_log(LOG_WARNING, "done, first %p\n", first);
+ // ast_log(LOG_WARNING, "done, first %p\n", first);
return first;
}
More information about the asterisk-commits
mailing list