/* * Asterisk -- An open source telephony toolkit. * * Copyright 2007-2008, Sergio Fadda, Luigi Rizzo * * See http://www.asterisk.org for more information about * the Asterisk project. Please do not directly contact * any of the maintainers of this project for assistance; * the project provides a web site, mailing lists and IRC * channels for your use. * * This program is free software, distributed under the terms of * the GNU General Public License Version 2. See the LICENSE file * at the top of the source tree. */ /* * Video codecs support for console_video.c * $Revision$ */ #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; struct fbuf_t; /* * Each codec is defined by a number of callbacks */ /*! \brief initialize the encoder */ typedef int (*encoder_init_f)(AVCodecContext *v); /*! \brief actually call the encoder */ typedef int (*encoder_encode_f)(struct video_out_desc *v); /*! \brief encapsulate the bistream in RTP frames */ typedef struct ast_frame *(*encoder_encap_f)(struct fbuf_t *, int mtu, struct ast_frame **tail); /*! \brief inizialize the decoder */ typedef int (*decoder_init_f)(AVCodecContext *enc_ctx); /*! \brief extract the bitstream from RTP frames and store in the fbuf. * return 0 if ok, 1 on error */ typedef int (*decoder_decap_f)(struct fbuf_t *b, uint8_t *data, int len); /*! \brief actually call the decoder */ typedef int (*decoder_decode_f)(struct video_dec_desc *v, struct fbuf_t *b); struct video_codec_desc { const char *name; /* format name */ int format; /* AST_FORMAT_* */ encoder_init_f enc_init; encoder_encap_f enc_encap; encoder_encode_f enc_run; decoder_init_f dec_init; decoder_decap_f dec_decap; decoder_decode_f dec_run; }; /* * Descriptor for the incoming stream, with multiple buffers for the bitstream * extracted from the RTP packets, RTP reassembly info, and a frame buffer * for the decoded frame (buf). * The descriptor is allocated as the first frame comes in. * * Incoming payload is stored in one of the dec_in[] buffers, which are * emptied by the video thread. These buffers are organized in a circular * queue, with dec_in_cur being the buffer in use by the incoming stream, * and dec_in_dpy is the one being displayed. When the pointers need to * be changed, we synchronize the access to them with dec_lock. * When the list is full dec_in_cur = NULL (we cannot store new data), * when the list is empty dec_in_dpy = NULL (we cannot display frames). */ struct video_dec_desc { struct video_codec_desc *d_callbacks; /* decoder callbacks */ AVCodecContext *dec_ctx; /* information about the codec in the stream */ AVCodec *codec; /* reference to the codec */ AVFrame *d_frame; /* place to store the decoded frame */ AVCodecParserContext *parser; uint16_t next_seq; /* must be 16 bit */ int discard; /* flag for discard status */ #define N_DEC_IN 3 /* number of incoming buffers */ struct fbuf_t *dec_in_cur; /* buffer being filled in */ struct fbuf_t *dec_in_dpy; /* buffer to display */ struct fbuf_t dec_in[N_DEC_IN]; /* incoming bitstream, allocated/extended in fbuf_append() */ struct fbuf_t dec_out; /* decoded frame, no buffer (data is in AVFrame) */ }; #ifdef debugging_only /* some debugging code to check the bitstream: * declare a bit buffer, initialize it, and fetch data from it. */ struct bitbuf { const uint8_t *base; int bitsize; /* total size in bits */ int ofs; /* next bit to read */ }; static struct bitbuf bitbuf_init(const uint8_t *base, int bitsize, int start_ofs) { struct bitbuf a; a.base = base; a.bitsize = bitsize; a.ofs = start_ofs; return a; } static int bitbuf_left(struct bitbuf *b) { return b->bitsize - b->ofs; } static uint32_t getbits(struct bitbuf *b, int n) { int i, ofs; const uint8_t *d; uint8_t mask; uint32_t retval = 0; if (n> 31) { ast_log(LOG_WARNING, "too many bits %d, max 32\n", n); return 0; } if (n + b->ofs > b->bitsize) { ast_log(LOG_WARNING, "bitbuf overflow %d of %d\n", n + b->ofs, b->bitsize); n = b->bitsize - b->ofs; } ofs = 7 - b->ofs % 8; /* start from msb */ mask = 1 << ofs; d = b->base + b->ofs / 8; /* current byte */ for (i=0 ; i < n; i++) { retval += retval + (*d & mask ? 1 : 0); /* shift in new byte */ b->ofs++; mask >>= 1; if (mask == 0) { d++; mask = 0x80; } } return retval; } static void check_h261(struct fbuf_t *b) { struct bitbuf a = bitbuf_init(b->data, b->used * 8, 0); uint32_t x, y; x = getbits(&a, 20); /* PSC, 0000 0000 0000 0001 0000 */ if (x != 0x10) { ast_log(LOG_WARNING, "bad PSC 0x%x\n", x); return; } x = getbits(&a, 5); /* temporal reference */ y = getbits(&a, 6); /* ptype */ if (0) ast_log(LOG_WARNING, "size %d TR %d PTY spl %d doc %d freeze %d %sCIF hi %d\n", b->used, x, (y & 0x20) ? 1 : 0, (y & 0x10) ? 1 : 0, (y & 0x8) ? 1 : 0, (y & 0x4) ? "" : "Q", (y & 0x2) ? 1:0); while ( (x = getbits(&a, 1)) == 1) ast_log(LOG_WARNING, "PSPARE 0x%x\n", getbits(&a, 8)); // ast_log(LOG_WARNING, "PSPARE 0 - start GOB LAYER\n"); while ( (x = bitbuf_left(&a)) > 0) { // ast_log(LOG_WARNING, "GBSC %d bits left\n", x); x = getbits(&a, 16); /* GBSC 0000 0000 0000 0001 */ if (x != 0x1) { ast_log(LOG_WARNING, "bad GBSC 0x%x\n", x); break; } x = getbits(&a, 4); /* group number */ y = getbits(&a, 5); /* gquant */ if (x == 0) { ast_log(LOG_WARNING, " bad GN %d\n", x); break; } while ( (x = getbits(&a, 1)) == 1) ast_log(LOG_WARNING, "GSPARE 0x%x\n", getbits(&a, 8)); while ( (x = bitbuf_left(&a)) > 0) { /* MB layer */ break; } } } void dump_buf(struct fbuf_t *b); void dump_buf(struct fbuf_t *b) { int i, x, last2lines; char buf[80]; last2lines = (b->used - 16) & ~0xf; ast_log(LOG_WARNING, "buf size %d of %d\n", b->used, b->size); for (i = 0; i < b->used; i++) { x = i & 0xf; if ( x == 0) { /* new line */ if (i != 0) ast_log(LOG_WARNING, "%s\n", buf); memset(buf, '\0', sizeof(buf)); sprintf(buf, "%04x: ", i); } sprintf(buf + 6 + x*3, "%02x ", b->data[i]); if (i > 31 && i < last2lines) i = last2lines - 1; } if (buf[0]) ast_log(LOG_WARNING, "%s\n", buf); } #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.ptr = 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. * For each of them, we need to provide routines for initialization, * calling the encoder, encapsulating the bitstream in ast_frames, * extracting payload from ast_frames, and calling the decoder. */ /*--- h263+ support --- */ /*! \brief initialization of h263p */ static int h263p_enc_init(AVCodecContext *enc_ctx) { /* modes supported are - Unrestricted Motion Vector (annex D) - Advanced Prediction (annex F) - Advanced Intra Coding (annex I) - Deblocking Filter (annex J) - Slice Structure (annex K) - Alternative Inter VLC (annex S) - Modified Quantization (annex T) */ enc_ctx->flags |=CODEC_FLAG_H263P_UMV; /* annex D */ enc_ctx->flags |=CODEC_FLAG_AC_PRED; /* annex f ? */ enc_ctx->flags |=CODEC_FLAG_H263P_SLICE_STRUCT; /* annex k */ enc_ctx->flags |= CODEC_FLAG_H263P_AIC; /* annex I */ return 0; } /* * Create RTP/H.263 fragments to avoid IP fragmentation. We fragment on a * 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 fbuf_t *b, int mtu, struct ast_frame **tail) { struct ast_frame *cur = NULL, *first = NULL; 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) { uint8_t *data; struct ast_frame *f; int i, h; if (len >= 3 && d[0] == 0 && d[1] == 0 && d[2] >= 0x80) { /* we are starting a new block, so look for a PSC. */ for (i = 3; i < len - 3; i++) { if (d[i] == 0 && d[i+1] == 0 && d[i+2] >= 0x80) { l = i; break; } } } if (l > mtu || l > len) { /* psc not found, split */ l = MIN(len, mtu); } if (l < 1 || l > mtu) { ast_log(LOG_WARNING, "--- frame error l %d\n", l); break; } if (d[0] == 0 && d[1] == 0) { /* we start with a psc */ h = 0; } else { /* no psc, create a header */ h = 2; } f = create_video_frame(d, d+l, AST_FORMAT_H263_PLUS, h, cur); if (!f) break; data = f->data.ptr; if (h == 0) { /* we start with a psc */ data[0] |= 0x04; // set P == 1, and we are done } else { /* no psc, create a header */ data[0] = data[1] = 0; // P == 0 } if (!cur) first = f; cur = f; } if (cur) cur->subclass |= 1; // RTP Marker *tail = cur; /* end of the list */ return first; } /*! \brief extract the bitstreem from the RTP payload. * This is format dependent. * For h263+, the format is defined in RFC 2429 * and basically has a fixed 2-byte header as follows: * 5 bits RR reserved, shall be 0 * 1 bit P indicate a start/end condition, * in which case the payload should be prepended * by two zero-valued bytes. * 1 bit V there is an additional VRC header after this header * 6 bits PLEN length in bytes of extra picture header * 3 bits PEBIT how many bits to be ignored in the last byte * * XXX the code below is not complete. */ static int h263p_decap(struct fbuf_t *b, uint8_t *data, int len) { int PLEN; if (len < 2) { ast_log(LOG_WARNING, "invalid framesize %d\n", len); return 1; } PLEN = ( (data[0] & 1) << 5 ) | ( (data[1] & 0xf8) >> 3); if (PLEN > 0) { data += PLEN; len -= PLEN; } if (data[0] & 4) /* bit P */ data[0] = data[1] = 0; else { data += 2; len -= 2; } return fbuf_append(b, data, len, 0, 0); /* ignore trail bits */ } /* * generic encoder, used by the various protocols supported here. * We assume that the buffer is empty at the beginning. */ static int ffmpeg_encode(struct video_out_desc *v) { struct fbuf_t *b = &v->enc_out; int i; b->used = avcodec_encode_video(v->enc_ctx, b->data, b->size, v->enc_in_frame); i = avcodec_encode_video(v->enc_ctx, b->data + b->used, b->size - b->used, NULL); /* delayed frames ? */ if (i > 0) { ast_log(LOG_WARNING, "have %d more bytes\n", i); b->used += i; } return 0; } /* * Generic decoder, which is used by h263p, h263 and h261 as it simply * invokes ffmpeg's decoder. * av_parser_parse should merge a randomly chopped up stream into * proper frames. After that, if we have a valid frame, we decode it * until the entire frame is processed. */ static int ffmpeg_decode(struct video_dec_desc *v, struct fbuf_t *b) { uint8_t *src = b->data; int srclen = b->used; int full_frame = 0; if (srclen == 0) /* no data */ return 0; while (srclen) { uint8_t *data; int datalen, ret; int len = av_parser_parse(v->parser, v->dec_ctx, &data, &datalen, src, srclen, 0, 0); src += len; srclen -= len; /* The parser might return something it cannot decode, so it skips * the block returning no data */ if (data == NULL || datalen == 0) continue; ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame, data, datalen); if (full_frame == 1) /* full frame */ break; if (ret < 0) { ast_log(LOG_NOTICE, "Error decoding\n"); break; } } if (srclen != 0) /* update b with leftover data */ memmove(b->data, src, srclen); b->used = srclen; b->ebit = 0; return full_frame; } static struct video_codec_desc h263p_codec = { .name = "h263p", .format = AST_FORMAT_H263_PLUS, .enc_init = h263p_enc_init, .enc_encap = h263p_encap, .enc_run = ffmpeg_encode, .dec_init = NULL, .dec_decap = h263p_decap, .dec_run = ffmpeg_decode }; /*--- Plain h263 support --------*/ static int h263_enc_init(AVCodecContext *enc_ctx) { /* XXX check whether these are supported */ enc_ctx->flags |= CODEC_FLAG_H263P_UMV; enc_ctx->flags |= CODEC_FLAG_H263P_AIC; enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; enc_ctx->flags |= CODEC_FLAG_AC_PRED; return 0; } /* * h263 encapsulation is specified in RFC2190. There are three modes * defined (A, B, C), with 4, 8 and 12 bytes of header, respectively. * The header is made as follows * 0.....................|.......................|.............|....31 * F:1 P:1 SBIT:3 EBIT:3 SRC:3 I:1 U:1 S:1 A:1 R:4 DBQ:2 TRB:3 TR:8 * FP = 0- mode A, (only one word of header) * FP = 10 mode B, and also means this is an I or P frame * FP = 11 mode C, and also means this is a PB frame. * SBIT, EBIT nuber of bits to ignore at beginning (msbits) and end (lsbits) * SRC bits 6,7,8 from the h263 PTYPE field * I = 0 intra-coded, 1 = inter-coded (bit 9 from PTYPE) * U = 1 for Unrestricted Motion Vector (bit 10 from PTYPE) * S = 1 for Syntax Based Arith coding (bit 11 from PTYPE) * A = 1 for Advanced Prediction (bit 12 from PTYPE) * R = reserved, must be 0 * DBQ = differential quantization, DBQUANT from h263, 0 unless we are using * PB frames * TRB = temporal reference for bframes, also 0 unless this is a PB frame * TR = temporal reference for P frames, also 0 unless PB frame. * * Mode B and mode C description omitted. * * 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 fbuf_t *b, int mtu, struct ast_frame **tail) { 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 */ uint8_t *h = h263_hdr; /* shorthand */ #define H263_MIN_LEN 6 if (len < H263_MIN_LEN) /* unreasonably small */ return NULL; memset(h263_hdr, '\0', 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, i += 3) { //ast_log(LOG_WARNING, "search at %d of %d/%d\n", i, start, len); for (; i < len ; i++) { uint8_t x, rpos, lpos; int rpos_i; /* index corresponding to rpos */ 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_i = 8; rpos; rpos >>= 1, rpos_i--) 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 %d\n", rpos, rpos_i); } break; } /* This frame is up to offset i (not inclusive). * We do not split it yet even if larger than MTU. */ f = create_video_frame(d + start, d+i, AST_FORMAT_H263, pheader_len, cur); if (!f) break; memmove(f->data.ptr, h, 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 */ if (!cur) first = f; cur = f; } if (cur) cur->subclass |= 1; // RTP Marker *tail = cur; return first; } /* XXX We only drop the header here, but maybe we need more. */ static int h263_decap(struct fbuf_t *b, uint8_t *data, int len) { if (len < 4) { ast_log(LOG_WARNING, "invalid framesize %d\n", len); return 1; /* error */ } if ( (data[0] & 0x80) == 0) { len -= 4; data += 4; } else { ast_log(LOG_WARNING, "unsupported mode 0x%x\n", data[0]); return 1; } return fbuf_append(b, data, len, 0, 0); /* XXX no bit alignment support yet */ } static struct video_codec_desc h263_codec = { .name = "h263", .format = AST_FORMAT_H263, .enc_init = h263_enc_init, .enc_encap = h263_encap, .enc_run = ffmpeg_encode, .dec_init = NULL, .dec_decap = h263_decap, .dec_run = ffmpeg_decode }; /*---- h261 support -----*/ static int h261_enc_init(AVCodecContext *enc_ctx) { /* It is important to set rtp_payload_size = 0, otherwise * ffmpeg in h261 mode will produce output that it cannot parse. * Also try to send I frames more frequently than with other codecs. */ enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */ return 0; } /* * The encapsulation of H261 is defined in RFC4587 which obsoletes RFC2032 * The bitstream is preceded by a 32-bit header word: * SBIT:3 EBIT:3 I:1 V:1 GOBN:4 MBAP:5 QUANT:5 HMVD:5 VMVD:5 * SBIT and EBIT are the bits to be ignored at beginning and end, * I=1 if the stream has only INTRA frames - cannot change during the stream. * V=0 if motion vector is not used. Cannot change. * GOBN is the GOB number in effect at the start of packet, 0 if we * start with a GOB header * QUANT is the quantizer in effect, 0 if we start with GOB header * HMVD reference horizontal motion vector. 10000 is forbidden * VMVD reference vertical motion vector, as above. * Packetization should occur at GOB boundaries, and if not possible * 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 fbuf_t *b, int mtu, struct ast_frame **tail) { 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]; uint8_t *h = h261_hdr; /* shorthand */ int sbit = 0, ebit = 0; #define H261_MIN_LEN 10 if (len < H261_MIN_LEN) /* unreasonably small */ return NULL; memset(h261_hdr, '\0', sizeof(h261_hdr)); /* Similar to the code in h263_encap, but the marker there is longer. * Start a few bytes within the bitstream to avoid hitting the marker * twice. Note we might access the buffer at len, but this is ok because * the caller has it oversized. */ for (i = H261_MIN_LEN, start = 0; start < len - 1; start = i, i += 4) { #if 0 /* test - disable packetization */ i = len; /* wrong... */ #else int found = 0, found_ebit = 0; /* last GBSC position found */ for (; i < len ; i++) { uint8_t x, rpos, lpos; if (d[i] != 0) /* cannot be in a GBSC */ continue; x = d[i+1]; if (x == 0) /* next is equally good */ continue; /* See if around us we find 15 '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, ebit = 7; rpos; ebit--, rpos >>= 1) if (x & rpos) /* found the '1' bit in GBSC */ break; x = d[i-1]; /* now look behind */ for (lpos = (rpos >> 1); 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. Just remember it. */ if (i - start > mtu) /* too large, stop now */ break; found_ebit = ebit; found = i; i += 4; /* continue forward */ } if (i >= len) { /* trim if we went too forward */ i = len; ebit = 0; /* hopefully... should ask the bitstream ? */ } if (i - start > mtu && found) { /* use the previous GBSC, hope is within the mtu */ i = found; ebit = found_ebit; } #endif /* test */ if (i - start < 4) /* XXX too short ? */ continue; /* This frame is up to offset i (not inclusive). * We do not split it yet even if larger than MTU. */ f = create_video_frame(d + start, d+i, AST_FORMAT_H261, pheader_len, cur); if (!f) break; /* recompute header with I=0, V=1 */ h[0] = ( (sbit & 7) << 5 ) | ( (ebit & 7) << 2 ) | 1; memmove(f->data.ptr, h, 4); /* copy the h261 header */ if (ebit) /* not aligned, restart from previous byte */ i--; sbit = (8 - ebit) & 7; ebit = 0; if (!cur) first = f; cur = f; } if (cur) cur->subclass |= 1; // RTP Marker *tail = cur; return first; } /* * Pieces might be unaligned so we really need to put them together. */ static int h261_decap(struct fbuf_t *b, uint8_t *data, int len) { int ebit, sbit; if (len < 8) { ast_log(LOG_WARNING, "invalid framesize %d\n", len); return 1; } sbit = (data[0] >> 5) & 7; ebit = (data[0] >> 2) & 7; len -= 4; data += 4; return fbuf_append(b, data, len, sbit, ebit); } static struct video_codec_desc h261_codec = { .name = "h261", .format = AST_FORMAT_H261, .enc_init = h261_enc_init, .enc_encap = h261_encap, .enc_run = ffmpeg_encode, .dec_init = NULL, .dec_decap = h261_decap, .dec_run = ffmpeg_decode }; /* mpeg4 support */ static int mpeg4_enc_init(AVCodecContext *enc_ctx) { #if 0 //enc_ctx->flags |= CODEC_FLAG_LOW_DELAY; /*don't use b frames ?*/ enc_ctx->flags |= CODEC_FLAG_AC_PRED; enc_ctx->flags |= CODEC_FLAG_H263P_UMV; enc_ctx->flags |= CODEC_FLAG_QPEL; enc_ctx->flags |= CODEC_FLAG_4MV; enc_ctx->flags |= CODEC_FLAG_GMC; enc_ctx->flags |= CODEC_FLAG_LOOP_FILTER; enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT; #endif enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */ return 0; } /* simplistic encapsulation - just split frames in mtu-size units */ 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 = b->data; uint8_t *end = d + b->used; int len; for (;d < end; d += len, cur = f) { len = MIN(mtu, end - d); f = create_video_frame(d, d + len, AST_FORMAT_MP4_VIDEO, 0, cur); if (!f) break; if (!first) first = f; } if (cur) cur->subclass |= 1; *tail = cur; return first; } static int mpeg4_decap(struct fbuf_t *b, uint8_t *data, int len) { return fbuf_append(b, data, len, 0, 0); } static int mpeg4_decode(struct video_dec_desc *v, struct fbuf_t *b) { int full_frame = 0, datalen = b->used; int ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame, b->data, datalen); if (ret < 0) { ast_log(LOG_NOTICE, "Error decoding\n"); ret = datalen; /* assume we used everything. */ } datalen -= ret; if (datalen > 0) /* update b with leftover bytes */ memmove(b->data, b->data + ret, datalen); b->used = datalen; b->ebit = 0; return full_frame; } static struct video_codec_desc mpeg4_codec = { .name = "mpeg4", .format = AST_FORMAT_MP4_VIDEO, .enc_init = mpeg4_enc_init, .enc_encap = mpeg4_encap, .enc_run = ffmpeg_encode, .dec_init = NULL, .dec_decap = mpeg4_decap, .dec_run = mpeg4_decode }; static int h264_enc_init(AVCodecContext *enc_ctx) { enc_ctx->flags |= CODEC_FLAG_TRUNCATED; //enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER; //enc_ctx->flags2 |= CODEC_FLAG2_FASTPSKIP; /* TODO: Maybe we need to add some other flags */ enc_ctx->rtp_mode = 0; enc_ctx->rtp_payload_size = 0; enc_ctx->bit_rate_tolerance = enc_ctx->bit_rate; return 0; } static int h264_dec_init(AVCodecContext *dec_ctx) { dec_ctx->flags |= CODEC_FLAG_TRUNCATED; return 0; } /* * The structure of a generic H.264 stream is: * - 0..n 0-byte(s), unused, optional. one zero-byte is always present * in the first NAL before the start code prefix. * - start code prefix (3 bytes): 0x000001 * (the first bytestream has a * like these 0x00000001!) * - NAL header byte ( F[1] | NRI[2] | Type[5] ) where type != 0 * - byte-stream * - 0..n 0-byte(s) (padding, unused). * Segmentation in RTP only needs to be done on start code prefixes. * 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 fbuf_t *b, int mtu, struct ast_frame **tail) { struct ast_frame *f = NULL, *cur = NULL, *first = NULL; 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. */ #define HAVE_NAL(x) (x[-4] == 0 && x[-3] == 0 && x[-2] == 0 && x[-1] == 1) for (start += 4; start < end; start++) { int ty = start[0] & 0x1f; if (HAVE_NAL(start) && ty != 0 && ty != 31) break; } /* if not found, or too short, we just skip the next loop and are done. */ /* Here follows the main loop to create frames. Search subsequent start * codes, and then possibly fragment the unit into smaller fragments. */ for (;start < end - 4; start = d) { int size; /* size of current block */ uint8_t hdr[2]; /* add-on header when fragmenting */ int ty = 0; /* now search next nal */ for (d = start + 4; d < end; d++) { ty = d[0] & 0x1f; if (HAVE_NAL(d)) break; /* found NAL */ } /* have a block to send. d past the start code unless we overflow */ if (d >= end) { /* NAL not found */ 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 - (uint8_t *)b->data, b->used); continue; } size = d - start - 4; /* don't count the end */ if (size < mtu) { // test - don't fragment // Single NAL Unit f = create_video_frame(start, d - 4, AST_FORMAT_H264, 0, cur); if (!f) break; if (!first) first = f; cur = f; continue; } // Fragmented Unit (Mode A: no DON, very weak) hdr[0] = (*start & 0xe0) | 28; /* mark as a fragmentation unit */ hdr[1] = (*start++ & 0x1f) | 0x80 ; /* keep type and set START bit */ size--; /* skip the NAL header */ while (size) { uint8_t *data; int frag_size = MIN(size, mtu); f = create_video_frame(start, start+frag_size, AST_FORMAT_H264, 2, cur); if (!f) break; size -= frag_size; /* skip this data block */ start += frag_size; data = f->data.ptr; data[0] = hdr[0]; data[1] = hdr[1] | (size == 0 ? 0x40 : 0); /* end bit if we are done */ hdr[1] &= ~0x80; /* clear start bit for subsequent frames */ if (!first) first = f; cur = f; } } if (cur) cur->subclass |= 1; // RTP Marker *tail = cur; return first; } static int h264_decap(struct fbuf_t *b, uint8_t *data, int len) { /* Start Code Prefix (Annex B in specification) */ uint8_t scp[] = { 0x00, 0x00, 0x00, 0x01 }; int retval = 0; int type, ofs = 0; if (len < 2) { ast_log(LOG_WARNING, "--- invalid len %d\n", len); return 1; } /* first of all, check if the packet has F == 0 */ if (data[0] & 0x80) { ast_log(LOG_WARNING, "--- forbidden packet; nal: %02x\n", data[0]); return 1; } type = data[0] & 0x1f; switch (type) { case 0: case 31: ast_log(LOG_WARNING, "--- invalid type: %d\n", type); return 1; case 24: case 25: case 26: case 27: case 29: ast_log(LOG_WARNING, "--- encapsulation not supported : %d\n", type); return 1; case 28: /* FU-A Unit */ if (data[1] & 0x80) { // S == 1, import F and NRI from next data[1] &= 0x1f; /* preserve type */ data[1] |= (data[0] & 0xe0); /* import F & NRI */ retval = fbuf_append(b, scp, sizeof(scp), 0, 0); ofs = 1; } else { ofs = 2; } break; default: /* From 1 to 23 (Single NAL Unit) */ retval = fbuf_append(b, scp, sizeof(scp), 0, 0); } if (!retval) retval = fbuf_append(b, data + ofs, len - ofs, 0, 0); if (retval) ast_log(LOG_WARNING, "result %d\n", retval); return retval; } static struct video_codec_desc h264_codec = { .name = "h264", .format = AST_FORMAT_H264, .enc_init = h264_enc_init, .enc_encap = h264_encap, .enc_run = ffmpeg_encode, .dec_init = h264_dec_init, .dec_decap = h264_decap, .dec_run = ffmpeg_decode }; /* * Table of translation between asterisk and ffmpeg formats. * We need also a field for read and write (encoding and decoding), because * e.g. H263+ uses different codec IDs in ffmpeg when encoding or decoding. */ struct _cm { /* map ffmpeg codec types to asterisk formats */ uint32_t ast_format; /* 0 is a terminator */ enum CodecID codec; enum { CM_RD = 1, CM_WR = 2, CM_RDWR = 3 } rw; /* read or write or both ? */ //struct video_codec_desc *codec_desc; }; static const struct _cm video_formats[] = { { AST_FORMAT_H263_PLUS, CODEC_ID_H263, CM_RD }, /* incoming H263P ? */ { AST_FORMAT_H263_PLUS, CODEC_ID_H263P, CM_WR }, { AST_FORMAT_H263, CODEC_ID_H263, CM_RD }, { AST_FORMAT_H263, CODEC_ID_H263, CM_WR }, { AST_FORMAT_H261, CODEC_ID_H261, CM_RDWR }, { AST_FORMAT_H264, CODEC_ID_H264, CM_RDWR }, { AST_FORMAT_MP4_VIDEO, CODEC_ID_MPEG4, CM_RDWR }, { 0, 0, 0 }, }; /*! \brief map an asterisk format into an ffmpeg one */ static enum CodecID map_video_format(uint32_t ast_format, int rw) { struct _cm *i; for (i = video_formats; i->ast_format != 0; i++) if (ast_format & i->ast_format && rw & i->rw && rw & i->rw) return i->codec; return CODEC_ID_NONE; } /* pointers to supported codecs. We assume the first one to be non null. */ static const struct video_codec_desc *supported_codecs[] = { &h263p_codec, &h264_codec, &h263_codec, &h261_codec, &mpeg4_codec, NULL }; /* * Map the AST_FORMAT to the library. If not recognised, fail. * This is useful in the input path where we get frames. */ static struct video_codec_desc *map_video_codec(int fmt) { int i; for (i = 0; supported_codecs[i]; i++) if (fmt == supported_codecs[i]->format) { ast_log(LOG_WARNING, "using %s for format 0x%x\n", supported_codecs[i]->name, fmt); return supported_codecs[i]; } return NULL; } /*! \brief uninitialize the descriptor for remote video stream */ static struct video_dec_desc *dec_uninit(struct video_dec_desc *v) { int i; if (v == NULL) /* not initialized yet */ return NULL; if (v->parser) { av_parser_close(v->parser); v->parser = NULL; } if (v->dec_ctx) { avcodec_close(v->dec_ctx); av_free(v->dec_ctx); v->dec_ctx = NULL; } if (v->d_frame) { av_free(v->d_frame); v->d_frame = NULL; } v->codec = NULL; /* only a reference */ v->d_callbacks = NULL; /* forget the decoder */ v->discard = 1; /* start in discard mode */ for (i = 0; i < N_DEC_IN; i++) fbuf_free(&v->dec_in[i]); fbuf_free(&v->dec_out); ast_free(v); return NULL; /* error, in case someone cares */ } /* * initialize ffmpeg resources used for decoding frames from the network. */ static struct video_dec_desc *dec_init(uint32_t the_ast_format) { enum CodecID codec; struct video_dec_desc *v = ast_calloc(1, sizeof(*v)); if (v == NULL) return NULL; v->discard = 1; v->d_callbacks = map_video_codec(the_ast_format); if (v->d_callbacks == NULL) { ast_log(LOG_WARNING, "cannot find video codec, drop input 0x%x\n", the_ast_format); return dec_uninit(v); } codec = map_video_format(v->d_callbacks->format, CM_RD); v->codec = avcodec_find_decoder(codec); if (!v->codec) { ast_log(LOG_WARNING, "Unable to find the decoder for format %d\n", codec); return dec_uninit(v); } /* * Initialize the codec context. */ v->dec_ctx = avcodec_alloc_context(); if (!v->dec_ctx) { ast_log(LOG_WARNING, "Cannot allocate the decoder context\n"); return dec_uninit(v); } /* XXX call dec_init() ? */ if (avcodec_open(v->dec_ctx, v->codec) < 0) { ast_log(LOG_WARNING, "Cannot open the decoder context\n"); av_free(v->dec_ctx); v->dec_ctx = NULL; return dec_uninit(v); } v->parser = av_parser_init(codec); if (!v->parser) { ast_log(LOG_WARNING, "Cannot initialize the decoder parser\n"); return dec_uninit(v); } v->d_frame = avcodec_alloc_frame(); if (!v->d_frame) { ast_log(LOG_WARNING, "Cannot allocate decoding video frame\n"); return dec_uninit(v); } v->dec_in_cur = &v->dec_in[0]; /* buffer for incoming frames */ v->dec_in_dpy = NULL; /* nothing to display */ return v; /* ok */ } /*------ end codec specific code -----*/