change the interface of video encapsulation routines, they only
authorLuigi Rizzo <rizzo@icir.org>
Fri, 28 Dec 2007 23:04:04 +0000 (23:04 +0000)
committerLuigi Rizzo <rizzo@icir.org>
Fri, 28 Dec 2007 23:04:04 +0000 (23:04 +0000)
need the buffer and mtu as input.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@95263 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/console_video.c
channels/vcodecs.c

index 18269ae..7001fae 100644 (file)
@@ -226,107 +226,6 @@ static void fbuf_free(struct fbuf_t *b)
        b->pix_fmt = x.pix_fmt;
 }
 
-/*
- * Append a chunk of data to a buffer taking care of bit alignment
- * Return 0 on success, != 0 on failure
- */
-static int fbuf_append(struct fbuf_t *b, uint8_t *src, int len,
-       int sbit, int ebit)
-{
-       /*
-        * Allocate buffer. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE,
-        * and also wants 0 as a buffer terminator to prevent trouble.
-        */
-       int need = len + FF_INPUT_BUFFER_PADDING_SIZE;
-       int i;
-       uint8_t *dst, mask;
-
-       if (b->data == NULL) {
-               b->size = need;
-               b->used = 0;
-               b->ebit = 0;
-               b->data = ast_calloc(1, b->size);
-       } else if (b->used + need > b->size) {
-               b->size = b->used + need;
-               b->data = ast_realloc(b->data, b->size);
-       }
-       if (b->data == NULL) {
-               ast_log(LOG_WARNING, "alloc failure for %d, discard\n",
-                       b->size);
-               return 1;
-       }
-       if (b->used == 0 && b->ebit != 0) {
-               ast_log(LOG_WARNING, "ebit not reset at start\n");
-               b->ebit = 0;
-       }
-       dst = b->data + b->used;
-       i = b->ebit + sbit;     /* bits to ignore around */
-       if (i == 0) {   /* easy case, just append */
-               /* do everything in the common block */
-       } else if (i == 8) { /* easy too, just handle the overlap byte */
-               mask = (1 << b->ebit) - 1;
-               /* update the last byte in the buffer */
-               dst[-1] &= ~mask;       /* clear bits to ignore */
-               dst[-1] |= (*src & mask);       /* append new bits */
-               src += 1;       /* skip and prepare for common block */
-               len --;
-       } else {        /* must shift the new block, not done yet */
-               ast_log(LOG_WARNING, "must handle shift %d %d at %d\n",
-                       b->ebit, sbit, b->used);
-               return 1;
-       }
-       memcpy(dst, src, len);
-       b->used += len;
-       b->ebit = ebit;
-       b->data[b->used] = 0;   /* padding */
-       return 0;
-}
-
-/*!
- * Build an ast_frame for a given chunk of data, and link it into
- * the queue, with possibly 'head' bytes at the beginning to
- * fill in some fields later.
- */
-static struct ast_frame *create_video_frame(uint8_t *start, uint8_t *end,
-                      int format, int head, struct ast_frame *prev)
-{
-       int len = end-start;
-       uint8_t *data;
-       struct ast_frame *f;
-
-       data = ast_calloc(1, len+head);
-       f = ast_calloc(1, sizeof(*f));
-       if (f == NULL || data == NULL) {
-               ast_log(LOG_WARNING, "--- frame error f %p data %p len %d format %d\n",
-                               f, data, len, format);
-               if (f)
-                       ast_free(f);
-               if (data)
-                       ast_free(data);
-               return NULL;
-       }
-       memcpy(data+head, start, len);
-       f->data = data;
-       f->mallocd = AST_MALLOCD_DATA | AST_MALLOCD_HDR;
-       //f->has_timing_info = 1;
-       //f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
-       f->datalen = len+head;
-       f->frametype = AST_FRAME_VIDEO;
-       f->subclass = format;
-       f->samples = 0;
-       f->offset = 0;
-       f->src = "Console";
-       f->delivery.tv_sec = 0;
-       f->delivery.tv_usec = 0;
-       f->seqno = 0;
-       AST_LIST_NEXT(f, frame_list) = NULL;
-
-       if (prev)
-               AST_LIST_NEXT(prev, frame_list) = f;
-
-       return f;
-}
-
 #include "vcodecs.c"
 #include "console_gui.c"
 
@@ -924,7 +823,7 @@ static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_fra
                return NULL;
        }
        v->enc->enc_run(v);
-       return v->enc->enc_encap(v, tail);
+       return v->enc->enc_encap(&v->enc_out, v->mtu, tail);
 }
 
 /*
index 8843981..8cb1f20 100644 (file)
@@ -6,6 +6,7 @@
 #include "asterisk.h"
 #include "console_video.h"
 #include "asterisk/frame.h"
+#include "asterisk/utils.h"    /* ast_calloc() */
 
 struct video_out_desc;
 struct video_dec_desc;
@@ -21,8 +22,7 @@ typedef int (*encoder_init_f)(AVCodecContext *v);
 typedef int (*encoder_encode_f)(struct video_out_desc *v);
 
 /*! \brief encapsulate the bistream in RTP frames */
-/* struct fbuf_t, int mtu, struct ast_frame **tail */
-typedef struct ast_frame *(*encoder_encap_f)(struct video_out_desc *out,
+typedef struct ast_frame *(*encoder_encap_f)(struct fbuf_t *, int mtu,
                struct ast_frame **tail);
 
 /*! \brief inizialize the decoder */
@@ -200,6 +200,107 @@ void dump_buf(struct fbuf_t *b)
 }
 #endif /* debugging_only */
 
+/*!
+ * Build an ast_frame for a given chunk of data, and link it into
+ * the queue, with possibly 'head' bytes at the beginning to
+ * fill in some fields later.
+ */
+static struct ast_frame *create_video_frame(uint8_t *start, uint8_t *end,
+                      int format, int head, struct ast_frame *prev)
+{
+       int len = end-start;
+       uint8_t *data;
+       struct ast_frame *f;
+
+       data = ast_calloc(1, len+head);
+       f = ast_calloc(1, sizeof(*f));
+       if (f == NULL || data == NULL) {
+               ast_log(LOG_WARNING, "--- frame error f %p data %p len %d format %d\n",
+                               f, data, len, format);
+               if (f)
+                       ast_free(f);
+               if (data)
+                       ast_free(data);
+               return NULL;
+       }
+       memcpy(data+head, start, len);
+       f->data = data;
+       f->mallocd = AST_MALLOCD_DATA | AST_MALLOCD_HDR;
+       //f->has_timing_info = 1;
+       //f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
+       f->datalen = len+head;
+       f->frametype = AST_FRAME_VIDEO;
+       f->subclass = format;
+       f->samples = 0;
+       f->offset = 0;
+       f->src = "Console";
+       f->delivery.tv_sec = 0;
+       f->delivery.tv_usec = 0;
+       f->seqno = 0;
+       AST_LIST_NEXT(f, frame_list) = NULL;
+
+       if (prev)
+               AST_LIST_NEXT(prev, frame_list) = f;
+
+       return f;
+}
+
+
+/*
+ * Append a chunk of data to a buffer taking care of bit alignment
+ * Return 0 on success, != 0 on failure
+ */
+static int fbuf_append(struct fbuf_t *b, uint8_t *src, int len,
+       int sbit, int ebit)
+{
+       /*
+        * Allocate buffer. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE,
+        * and also wants 0 as a buffer terminator to prevent trouble.
+        */
+       int need = len + FF_INPUT_BUFFER_PADDING_SIZE;
+       int i;
+       uint8_t *dst, mask;
+
+       if (b->data == NULL) {
+               b->size = need;
+               b->used = 0;
+               b->ebit = 0;
+               b->data = ast_calloc(1, b->size);
+       } else if (b->used + need > b->size) {
+               b->size = b->used + need;
+               b->data = ast_realloc(b->data, b->size);
+       }
+       if (b->data == NULL) {
+               ast_log(LOG_WARNING, "alloc failure for %d, discard\n",
+                       b->size);
+               return 1;
+       }
+       if (b->used == 0 && b->ebit != 0) {
+               ast_log(LOG_WARNING, "ebit not reset at start\n");
+               b->ebit = 0;
+       }
+       dst = b->data + b->used;
+       i = b->ebit + sbit;     /* bits to ignore around */
+       if (i == 0) {   /* easy case, just append */
+               /* do everything in the common block */
+       } else if (i == 8) { /* easy too, just handle the overlap byte */
+               mask = (1 << b->ebit) - 1;
+               /* update the last byte in the buffer */
+               dst[-1] &= ~mask;       /* clear bits to ignore */
+               dst[-1] |= (*src & mask);       /* append new bits */
+               src += 1;       /* skip and prepare for common block */
+               len --;
+       } else {        /* must shift the new block, not done yet */
+               ast_log(LOG_WARNING, "must handle shift %d %d at %d\n",
+                       b->ebit, sbit, b->used);
+               return 1;
+       }
+       memcpy(dst, src, len);
+       b->used += len;
+       b->ebit = ebit;
+       b->data[b->used] = 0;   /* padding */
+       return 0;
+}
 
 /*
  * Here starts the glue code for the various supported video codecs.
@@ -236,12 +337,12 @@ static int h263p_enc_init(AVCodecContext *enc_ctx)
  * PSC or a GBSC, but if we don't find a suitable place just break somewhere.
  * Everything is byte-aligned.
  */
-static struct ast_frame *h263p_encap(struct video_out_desc *out,
+static struct ast_frame *h263p_encap(struct fbuf_t *b, int mtu,
        struct ast_frame **tail)
 {
        struct ast_frame *cur = NULL, *first = NULL;
-       uint8_t *d = out->enc_out.data;
-       int len = out->enc_out.used;
+       uint8_t *d = b->data;
+       int len = b->used;
        int l = len; /* size of the current fragment. If 0, must look for a psc */
 
        for (;len > 0; len -= l, d += l) {
@@ -258,10 +359,10 @@ static struct ast_frame *h263p_encap(struct video_out_desc *out,
                                }
                        }
                }
-               if (l > out->mtu || l > len) { /* psc not found, split */
-                       l = MIN(len, out->mtu);
+               if (l > mtu || l > len) { /* psc not found, split */
+                       l = MIN(len, mtu);
                }
-               if (l < 1 || l > out->mtu) {
+               if (l < 1 || l > mtu) {
                        ast_log(LOG_WARNING, "--- frame error l %d\n", l);
                        break;
                }
@@ -451,11 +552,11 @@ static int h263_enc_init(AVCodecContext *enc_ctx)
  * 
  * The assumption below is that we start with a PSC.
  */
-static struct ast_frame *h263_encap(struct video_out_desc *out,
+static struct ast_frame *h263_encap(struct fbuf_t *b, int mtu,
                struct ast_frame **tail)
 {
-       uint8_t *d = out->enc_out.data;
-       int start = 0, i, len = out->enc_out.used;
+       uint8_t *d = b->data;
+       int start = 0, i, len = b->used;
        struct ast_frame *f, *cur = NULL, *first = NULL;
        const int pheader_len = 4;      /* Use RFC-2190 Mode A */
        uint8_t h263_hdr[12];   /* worst case, room for a type c header */
@@ -605,11 +706,11 @@ static int h261_enc_init(AVCodecContext *enc_ctx)
  * with MacroBlock fragmentation. However it is likely that blocks
  * are not bit-aligned so we must take care of this.
  */
-static struct ast_frame *h261_encap(struct video_out_desc *out,
+static struct ast_frame *h261_encap(struct fbuf_t *b, int mtu,
                struct ast_frame **tail)
 {
-       uint8_t *d = out->enc_out.data;
-       int start = 0, i, len = out->enc_out.used;
+       uint8_t *d = b->data;
+       int start = 0, i, len = b->used;
        struct ast_frame *f, *cur = NULL, *first = NULL;
        const int pheader_len = 4;
        uint8_t h261_hdr[4];
@@ -656,7 +757,7 @@ static struct ast_frame *h261_encap(struct video_out_desc *out,
                        /* now we have a GBSC starting somewhere in d[i-1],
                         * but it might be not byte-aligned. Just remember it.
                         */
-                       if (i - start > out->mtu) /* too large, stop now */
+                       if (i - start > mtu) /* too large, stop now */
                                break;
                        found_ebit = ebit;
                        found = i;
@@ -666,7 +767,7 @@ static struct ast_frame *h261_encap(struct video_out_desc *out,
                        i = len;
                        ebit = 0;       /* hopefully... should ask the bitstream ? */
                }
-               if (i - start > out->mtu && found) {
+               if (i - start > mtu && found) {
                        /* use the previous GBSC, hope is within the mtu */
                        i = found;
                        ebit = found_ebit;
@@ -747,17 +848,17 @@ static int mpeg4_enc_init(AVCodecContext *enc_ctx)
 }
 
 /* simplistic encapsulation - just split frames in mtu-size units */
-static struct ast_frame *mpeg4_encap(struct  video_out_desc *out,
+static struct ast_frame *mpeg4_encap(struct fbuf_t *b, int mtu,
        struct ast_frame **tail)
 {
        struct ast_frame *f, *cur = NULL, *first = NULL;
-       uint8_t *d = out->enc_out.data;
-       uint8_t *end = d+out->enc_out.used;
+       uint8_t *d = b->data;
+       uint8_t *end = d + b->used;
        int len;
 
        for (;d < end; d += len, cur = f) {
-               len = MIN(out->mtu, end-d);
-               f = create_video_frame(d, d+len, AST_FORMAT_MP4_VIDEO, 0, cur);
+               len = MIN(mtu, end - d);
+               f = create_video_frame(d, d + len, AST_FORMAT_MP4_VIDEO, 0, cur);
                if (!f)
                        break;
                if (!first)
@@ -835,12 +936,12 @@ static int h264_dec_init(AVCodecContext *dec_ctx)
  * If fragments are too long... we don't support it yet.
  * - encapsulate (or fragment) the byte-stream (with NAL header included)
  */
-static struct ast_frame *h264_encap(struct video_out_desc *out,
+static struct ast_frame *h264_encap(struct fbuf_t *b, int mtu,
        struct ast_frame **tail)
 {
        struct ast_frame *f = NULL, *cur = NULL, *first = NULL;
-       uint8_t *d, *start = out->enc_out.data;
-       uint8_t *end = start + out->enc_out.used;
+       uint8_t *d, *start = b->data;
+       uint8_t *end = start + b->used;
 
        /* Search the first start code prefix - ITU-T H.264 sec. B.2,
         * and move start right after that, on the NAL header byte.
@@ -872,13 +973,13 @@ static struct ast_frame *h264_encap(struct video_out_desc *out,
                d = end + 4;
        } else if (ty == 0 || ty == 31) { /* found but invalid type, skip */
                ast_log(LOG_WARNING, "skip invalid nal type %d at %d of %d\n",
-                       ty, d - out->enc_out.data, out->enc_out.used);
+                       ty, d - (uint8_t *)b->data, b->used);
                continue;
        }
 
        size = d - start - 4;   /* don't count the end */
 
-       if (size < out->mtu) {  // test - don't fragment
+       if (size < mtu) {       // test - don't fragment
                // Single NAL Unit
                f = create_video_frame(start, d - 4, AST_FORMAT_H264, 0, cur);
                if (!f)
@@ -896,7 +997,7 @@ static struct ast_frame *h264_encap(struct video_out_desc *out,
        size--;         /* skip the NAL header */
        while (size) {
                uint8_t *data;
-               int frag_size = MIN(size, out->mtu);
+               int frag_size = MIN(size, mtu);
 
                f = create_video_frame(start, start+frag_size, AST_FORMAT_H264, 2, cur);
                if (!f)