Asterisk - The Open Source Telephony Project GIT-master-7e7a603
Data Structures | Macros | Typedefs | Functions | Variables
vcodecs.c File Reference
#include "asterisk.h"
#include "console_video.h"
#include "asterisk/frame.h"
#include "asterisk/utils.h"
Include dependency graph for vcodecs.c:

Go to the source code of this file.

Data Structures

struct  _cm
 
struct  video_codec_desc
 
struct  video_dec_desc
 

Macros

#define H261_MIN_LEN   10
 
#define H263_MIN_LEN   6
 
#define HAVE_NAL(x)   (x[-4] == 0 && x[-3] == 0 && x[-2] == 0 && x[-1] == 1)
 
#define N_DEC_IN   3 /* number of incoming buffers */
 

Typedefs

typedef int(* decoder_decap_f) (struct fbuf_t *b, uint8_t *data, int len)
 extract the bitstream from RTP frames and store in the fbuf. return 0 if ok, 1 on error More...
 
typedef int(* decoder_decode_f) (struct video_dec_desc *v, struct fbuf_t *b)
 actually call the decoder More...
 
typedef int(* decoder_init_f) (AVCodecContext *enc_ctx)
 inizialize the decoder More...
 
typedef struct ast_frame *(* encoder_encap_f) (struct fbuf_t *, int mtu, struct ast_frame **tail)
 encapsulate the bistream in RTP frames More...
 
typedef int(* encoder_encode_f) (struct video_out_desc *v)
 actually call the encoder More...
 
typedef int(* encoder_init_f) (AVCodecContext *v)
 initialize the encoder More...
 

Functions

static struct ast_framecreate_video_frame (uint8_t *start, uint8_t *end, int format, int head, struct ast_frame *prev)
 
static struct video_dec_descdec_init (uint32_t the_ast_format)
 
static struct video_dec_descdec_uninit (struct video_dec_desc *v)
 uninitialize the descriptor for remote video stream More...
 
static int fbuf_append (struct fbuf_t *b, uint8_t *src, int len, int sbit, int ebit)
 
static int ffmpeg_decode (struct video_dec_desc *v, struct fbuf_t *b)
 
static int ffmpeg_encode (struct video_out_desc *v)
 
static int h261_decap (struct fbuf_t *b, uint8_t *data, int len)
 
static int h261_enc_init (AVCodecContext *enc_ctx)
 
static struct ast_frameh261_encap (struct fbuf_t *b, int mtu, struct ast_frame **tail)
 
static int h263_decap (struct fbuf_t *b, uint8_t *data, int len)
 
static int h263_enc_init (AVCodecContext *enc_ctx)
 
static struct ast_frameh263_encap (struct fbuf_t *b, int mtu, struct ast_frame **tail)
 
static int h263p_decap (struct fbuf_t *b, uint8_t *data, int len)
 extract the bitstream 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 More...
 
static int h263p_enc_init (AVCodecContext *enc_ctx)
 initialization of h263p More...
 
static struct ast_frameh263p_encap (struct fbuf_t *b, int mtu, struct ast_frame **tail)
 
static int h264_dec_init (AVCodecContext *dec_ctx)
 
static int h264_decap (struct fbuf_t *b, uint8_t *data, int len)
 
static int h264_enc_init (AVCodecContext *enc_ctx)
 
static struct ast_frameh264_encap (struct fbuf_t *b, int mtu, struct ast_frame **tail)
 
static struct video_codec_descmap_video_codec (int fmt)
 
static enum CodecID map_video_format (uint32_t ast_format, int rw)
 map an asterisk format into an ffmpeg one More...
 
static int mpeg4_decap (struct fbuf_t *b, uint8_t *data, int len)
 
static int mpeg4_decode (struct video_dec_desc *v, struct fbuf_t *b)
 
static int mpeg4_enc_init (AVCodecContext *enc_ctx)
 
static struct ast_framempeg4_encap (struct fbuf_t *b, int mtu, struct ast_frame **tail)
 

Variables

static struct video_codec_desc h261_codec
 
static struct video_codec_desc h263_codec
 
static struct video_codec_desc h263p_codec
 
static struct video_codec_desc h264_codec
 
static struct video_codec_desc mpeg4_codec
 
static const struct video_codec_descsupported_codecs []
 
static const struct _cm video_formats []
 

Macro Definition Documentation

◆ H261_MIN_LEN

#define H261_MIN_LEN   10

◆ H263_MIN_LEN

#define H263_MIN_LEN   6

◆ HAVE_NAL

#define HAVE_NAL (   x)    (x[-4] == 0 && x[-3] == 0 && x[-2] == 0 && x[-1] == 1)

◆ N_DEC_IN

#define N_DEC_IN   3 /* number of incoming buffers */

Definition at line 92 of file vcodecs.c.

Typedef Documentation

◆ decoder_decap_f

typedef int(* decoder_decap_f) (struct fbuf_t *b, uint8_t *data, int len)

extract the bitstream from RTP frames and store in the fbuf. return 0 if ok, 1 on error

Definition at line 54 of file vcodecs.c.

◆ decoder_decode_f

typedef int(* decoder_decode_f) (struct video_dec_desc *v, struct fbuf_t *b)

actually call the decoder

Definition at line 57 of file vcodecs.c.

◆ decoder_init_f

typedef int(* decoder_init_f) (AVCodecContext *enc_ctx)

inizialize the decoder

Definition at line 49 of file vcodecs.c.

◆ encoder_encap_f

typedef struct ast_frame *(* encoder_encap_f) (struct fbuf_t *, int mtu, struct ast_frame **tail)

encapsulate the bistream in RTP frames

Definition at line 42 of file vcodecs.c.

◆ encoder_encode_f

typedef int(* encoder_encode_f) (struct video_out_desc *v)

actually call the encoder

Definition at line 42 of file vcodecs.c.

◆ encoder_init_f

typedef int(* encoder_init_f) (AVCodecContext *v)

initialize the encoder

Definition at line 39 of file vcodecs.c.

Function Documentation

◆ create_video_frame()

static struct ast_frame * create_video_frame ( uint8_t *  start,
uint8_t *  end,
int  format,
int  head,
struct ast_frame prev 
)
static

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.

Definition at line 228 of file vcodecs.c.

230{
231 int len = end-start;
232 uint8_t *data;
233 struct ast_frame *f;
234
235 data = ast_calloc(1, len+head);
236 f = ast_calloc(1, sizeof(*f));
237 if (f == NULL || data == NULL) {
238 ast_log(LOG_WARNING, "--- frame error f %p data %p len %d format %d\n",
239 f, data, len, format);
240 if (f)
241 ast_free(f);
242 if (data)
243 ast_free(data);
244 return NULL;
245 }
246 memcpy(data+head, start, len);
247 f->data.ptr = data;
249 //f->has_timing_info = 1;
250 //f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
251 f->datalen = len+head;
253 f->subclass = format;
254 f->samples = 0;
255 f->offset = 0;
256 f->src = "Console";
257 f->delivery.tv_sec = 0;
258 f->delivery.tv_usec = 0;
259 f->seqno = 0;
261
262 if (prev)
263 AST_LIST_NEXT(prev, frame_list) = f;
264
265 return f;
266}
#define ast_free(a)
Definition: astmm.h:180
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
#define ast_log
Definition: astobj2.c:42
char * end
Definition: eagi_proxy.c:73
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define AST_MALLOCD_HDR
#define AST_MALLOCD_DATA
@ AST_FRAME_VIDEO
#define LOG_WARNING
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:439
#define NULL
Definition: resample.c:96
Data structure associated with a single frame of data.
struct ast_frame_subclass subclass
union ast_frame::@226 data
struct timeval delivery
enum ast_frame_type frametype
const char * src

References ast_calloc, AST_FRAME_VIDEO, ast_free, AST_LIST_NEXT, ast_log, AST_MALLOCD_DATA, AST_MALLOCD_HDR, ast_frame::data, ast_frame::datalen, ast_frame::delivery, end, ast_frame::frametype, len(), LOG_WARNING, ast_frame::mallocd, NULL, ast_frame::offset, ast_frame::ptr, ast_frame::samples, ast_frame::seqno, ast_frame::src, and ast_frame::subclass.

Referenced by h261_encap(), h263_encap(), h263p_encap(), h264_encap(), and mpeg4_encap().

◆ dec_init()

static struct video_dec_desc * dec_init ( uint32_t  the_ast_format)
static

Definition at line 1204 of file vcodecs.c.

1205{
1206 enum CodecID codec;
1207 struct video_dec_desc *v = ast_calloc(1, sizeof(*v));
1208 if (v == NULL)
1209 return NULL;
1210
1211 v->discard = 1;
1212
1213 v->d_callbacks = map_video_codec(the_ast_format);
1214 if (v->d_callbacks == NULL) {
1215 ast_log(LOG_WARNING, "cannot find video codec, drop input 0x%x\n", the_ast_format);
1216 return dec_uninit(v);
1217 }
1218
1220
1221 v->codec = avcodec_find_decoder(codec);
1222 if (!v->codec) {
1223 ast_log(LOG_WARNING, "Unable to find the decoder for format %d\n", codec);
1224 return dec_uninit(v);
1225 }
1226 /*
1227 * Initialize the codec context.
1228 */
1229 v->dec_ctx = avcodec_alloc_context();
1230 if (!v->dec_ctx) {
1231 ast_log(LOG_WARNING, "Cannot allocate the decoder context\n");
1232 return dec_uninit(v);
1233 }
1234 /* XXX call dec_init() ? */
1235 if (avcodec_open(v->dec_ctx, v->codec) < 0) {
1236 ast_log(LOG_WARNING, "Cannot open the decoder context\n");
1237 av_free(v->dec_ctx);
1238 v->dec_ctx = NULL;
1239 return dec_uninit(v);
1240 }
1241
1242 v->parser = av_parser_init(codec);
1243 if (!v->parser) {
1244 ast_log(LOG_WARNING, "Cannot initialize the decoder parser\n");
1245 return dec_uninit(v);
1246 }
1247
1248 v->d_frame = avcodec_alloc_frame();
1249 if (!v->d_frame) {
1250 ast_log(LOG_WARNING, "Cannot allocate decoding video frame\n");
1251 return dec_uninit(v);
1252 }
1253 v->dec_in_cur = &v->dec_in[0]; /* buffer for incoming frames */
1254 v->dec_in_dpy = NULL; /* nothing to display */
1255
1256 return v; /* ok */
1257}
AVCodec * codec
Definition: vcodecs.c:87
struct fbuf_t * dec_in_cur
Definition: vcodecs.c:93
AVCodecParserContext * parser
Definition: vcodecs.c:89
struct video_codec_desc * d_callbacks
Definition: vcodecs.c:85
AVCodecContext * dec_ctx
Definition: vcodecs.c:86
AVFrame * d_frame
Definition: vcodecs.c:88
struct fbuf_t * dec_in_dpy
Definition: vcodecs.c:94
struct fbuf_t dec_in[N_DEC_IN]
Definition: vcodecs.c:95
static enum CodecID map_video_format(uint32_t ast_format, int rw)
map an asterisk format into an ffmpeg one
Definition: vcodecs.c:1133
static struct video_codec_desc * map_video_codec(int fmt)
Definition: vcodecs.c:1158
static struct video_dec_desc * dec_uninit(struct video_dec_desc *v)
uninitialize the descriptor for remote video stream
Definition: vcodecs.c:1172

References ast_calloc, ast_log, video_dec_desc::codec, video_dec_desc::d_callbacks, video_dec_desc::d_frame, video_dec_desc::dec_ctx, video_dec_desc::dec_in, video_dec_desc::dec_in_cur, video_dec_desc::dec_in_dpy, dec_uninit(), video_dec_desc::discard, video_codec_desc::format, LOG_WARNING, map_video_codec(), map_video_format(), NULL, and video_dec_desc::parser.

◆ dec_uninit()

static struct video_dec_desc * dec_uninit ( struct video_dec_desc v)
static

uninitialize the descriptor for remote video stream

Definition at line 1172 of file vcodecs.c.

1173{
1174 int i;
1175
1176 if (v == NULL) /* not initialized yet */
1177 return NULL;
1178 if (v->parser) {
1179 av_parser_close(v->parser);
1180 v->parser = NULL;
1181 }
1182 if (v->dec_ctx) {
1183 avcodec_close(v->dec_ctx);
1184 av_free(v->dec_ctx);
1185 v->dec_ctx = NULL;
1186 }
1187 if (v->d_frame) {
1188 av_free(v->d_frame);
1189 v->d_frame = NULL;
1190 }
1191 v->codec = NULL; /* only a reference */
1192 v->d_callbacks = NULL; /* forget the decoder */
1193 v->discard = 1; /* start in discard mode */
1194 for (i = 0; i < N_DEC_IN; i++)
1195 fbuf_free(&v->dec_in[i]);
1196 fbuf_free(&v->dec_out);
1197 ast_free(v);
1198 return NULL; /* error, in case someone cares */
1199}
void fbuf_free(struct fbuf_t *)
struct fbuf_t dec_out
Definition: vcodecs.c:96
#define N_DEC_IN
Definition: vcodecs.c:92

References ast_free, video_dec_desc::codec, video_dec_desc::d_callbacks, video_dec_desc::d_frame, video_dec_desc::dec_ctx, video_dec_desc::dec_in, video_dec_desc::dec_out, video_dec_desc::discard, fbuf_free(), N_DEC_IN, NULL, and video_dec_desc::parser.

Referenced by dec_init().

◆ fbuf_append()

static int fbuf_append ( struct fbuf_t b,
uint8_t *  src,
int  len,
int  sbit,
int  ebit 
)
static

Definition at line 273 of file vcodecs.c.

275{
276 /*
277 * Allocate buffer. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE,
278 * and also wants 0 as a buffer terminator to prevent trouble.
279 */
280 int need = len + FF_INPUT_BUFFER_PADDING_SIZE;
281 int i;
282 uint8_t *dst, mask;
283
284 if (b->data == NULL) {
285 b->size = need;
286 b->used = 0;
287 b->ebit = 0;
288 b->data = ast_calloc(1, b->size);
289 } else if (b->used + need > b->size) {
290 b->size = b->used + need;
291 b->data = ast_realloc(b->data, b->size);
292 }
293 if (b->data == NULL) {
294 ast_log(LOG_WARNING, "alloc failure for %d, discard\n",
295 b->size);
296 return 1;
297 }
298 if (b->used == 0 && b->ebit != 0) {
299 ast_log(LOG_WARNING, "ebit not reset at start\n");
300 b->ebit = 0;
301 }
302 dst = b->data + b->used;
303 i = b->ebit + sbit; /* bits to ignore around */
304 if (i == 0) { /* easy case, just append */
305 /* do everything in the common block */
306 } else if (i == 8) { /* easy too, just handle the overlap byte */
307 mask = (1 << b->ebit) - 1;
308 /* update the last byte in the buffer */
309 dst[-1] &= ~mask; /* clear bits to ignore */
310 dst[-1] |= (*src & mask); /* append new bits */
311 src += 1; /* skip and prepare for common block */
312 len --;
313 } else { /* must shift the new block, not done yet */
314 ast_log(LOG_WARNING, "must handle shift %d %d at %d\n",
315 b->ebit, sbit, b->used);
316 return 1;
317 }
318 memcpy(dst, src, len);
319 b->used += len;
320 b->ebit = ebit;
321 b->data[b->used] = 0; /* padding */
322 return 0;
323}
#define ast_realloc(p, len)
A wrapper for realloc()
Definition: astmm.h:226
static struct test_val b

References ast_calloc, ast_log, ast_realloc, b, len(), LOG_WARNING, NULL, and ast_frame::src.

Referenced by h261_decap(), h263_decap(), h263p_decap(), h264_decap(), and mpeg4_decap().

◆ ffmpeg_decode()

static int ffmpeg_decode ( struct video_dec_desc v,
struct fbuf_t b 
)
static

Definition at line 482 of file vcodecs.c.

483{
484 uint8_t *src = b->data;
485 int srclen = b->used;
486 int full_frame = 0;
487
488 if (srclen == 0) /* no data */
489 return 0;
490 while (srclen) {
491 uint8_t *data;
492 int datalen, ret;
493 int len = av_parser_parse(v->parser, v->dec_ctx, &data, &datalen, src, srclen, 0, 0);
494
495 src += len;
496 srclen -= len;
497 /* The parser might return something it cannot decode, so it skips
498 * the block returning no data
499 */
500 if (data == NULL || datalen == 0)
501 continue;
502 ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame, data, datalen);
503 if (full_frame == 1) /* full frame */
504 break;
505 if (ret < 0) {
506 ast_log(LOG_NOTICE, "Error decoding\n");
507 break;
508 }
509 }
510 if (srclen != 0) /* update b with leftover data */
511 memmove(b->data, src, srclen);
512 b->used = srclen;
513 b->ebit = 0;
514 return full_frame;
515}
#define LOG_NOTICE

References ast_log, b, video_dec_desc::d_frame, fbuf_t::data, video_dec_desc::dec_ctx, len(), LOG_NOTICE, NULL, and video_dec_desc::parser.

◆ ffmpeg_encode()

static int ffmpeg_encode ( struct video_out_desc *  v)
static

Definition at line 461 of file vcodecs.c.

462{
463 struct fbuf_t *b = &v->enc_out;
464 int i;
465
466 b->used = avcodec_encode_video(v->enc_ctx, b->data, b->size, v->enc_in_frame);
467 i = avcodec_encode_video(v->enc_ctx, b->data + b->used, b->size - b->used, NULL); /* delayed frames ? */
468 if (i > 0) {
469 ast_log(LOG_WARNING, "have %d more bytes\n", i);
470 b->used += i;
471 }
472 return 0;
473}

References ast_log, b, LOG_WARNING, and NULL.

◆ h261_decap()

static int h261_decap ( struct fbuf_t b,
uint8_t *  data,
int  len 
)
static

Definition at line 827 of file vcodecs.c.

828{
829 int ebit, sbit;
830
831 if (len < 8) {
832 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
833 return 1;
834 }
835 sbit = (data[0] >> 5) & 7;
836 ebit = (data[0] >> 2) & 7;
837 len -= 4;
838 data += 4;
839 return fbuf_append(b, data, len, sbit, ebit);
840}
static int fbuf_append(struct fbuf_t *b, uint8_t *src, int len, int sbit, int ebit)
Definition: vcodecs.c:273

References ast_log, b, ast_frame::data, fbuf_append(), len(), and LOG_WARNING.

◆ h261_enc_init()

static int h261_enc_init ( AVCodecContext *  enc_ctx)
static

Definition at line 702 of file vcodecs.c.

703{
704 /* It is important to set rtp_payload_size = 0, otherwise
705 * ffmpeg in h261 mode will produce output that it cannot parse.
706 * Also try to send I frames more frequently than with other codecs.
707 */
708 enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */
709
710 return 0;
711}

◆ h261_encap()

static struct ast_frame * h261_encap ( struct fbuf_t b,
int  mtu,
struct ast_frame **  tail 
)
static

Definition at line 729 of file vcodecs.c.

731{
732 uint8_t *d = b->data;
733 int start = 0, i, len = b->used;
734 struct ast_frame *f, *cur = NULL, *first = NULL;
735 const int pheader_len = 4;
736 uint8_t h261_hdr[4];
737 uint8_t *h = h261_hdr; /* shorthand */
738 int sbit = 0, ebit = 0;
739
740#define H261_MIN_LEN 10
741 if (len < H261_MIN_LEN) /* unreasonably small */
742 return NULL;
743
744 memset(h261_hdr, '\0', sizeof(h261_hdr));
745
746 /* Similar to the code in h263_encap, but the marker there is longer.
747 * Start a few bytes within the bitstream to avoid hitting the marker
748 * twice. Note we might access the buffer at len, but this is ok because
749 * the caller has it oversized.
750 */
751 for (i = H261_MIN_LEN, start = 0; start < len - 1; start = i, i += 4) {
752#if 0 /* test - disable packetization */
753 i = len; /* wrong... */
754#else
755 int found = 0, found_ebit = 0; /* last GBSC position found */
756 for (; i < len ; i++) {
757 uint8_t x, rpos, lpos;
758 if (d[i] != 0) /* cannot be in a GBSC */
759 continue;
760 x = d[i+1];
761 if (x == 0) /* next is equally good */
762 continue;
763 /* See if around us we find 15 '0' bits for the GBSC.
764 * Look for the first bit set on the right, and then
765 * see if we have enough 0 on the left.
766 * We are guaranteed to end before rpos == 0
767 */
768 for (rpos = 0x80, ebit = 7; rpos; ebit--, rpos >>= 1)
769 if (x & rpos) /* found the '1' bit in GBSC */
770 break;
771 x = d[i-1]; /* now look behind */
772 for (lpos = (rpos >> 1); lpos ; lpos >>= 1)
773 if (x & lpos) /* too early, not a GBSC */
774 break;
775 if (lpos) /* as i said... */
776 continue;
777 /* now we have a GBSC starting somewhere in d[i-1],
778 * but it might be not byte-aligned. Just remember it.
779 */
780 if (i - start > mtu) /* too large, stop now */
781 break;
782 found_ebit = ebit;
783 found = i;
784 i += 4; /* continue forward */
785 }
786 if (i >= len) { /* trim if we went too forward */
787 i = len;
788 ebit = 0; /* hopefully... should ask the bitstream ? */
789 }
790 if (i - start > mtu && found) {
791 /* use the previous GBSC, hope is within the mtu */
792 i = found;
793 ebit = found_ebit;
794 }
795#endif /* test */
796 if (i - start < 4) /* XXX too short ? */
797 continue;
798 /* This frame is up to offset i (not inclusive).
799 * We do not split it yet even if larger than MTU.
800 */
801 f = create_video_frame(d + start, d+i, AST_FORMAT_H261,
802 pheader_len, cur);
803
804 if (!f)
805 break;
806 /* recompute header with I=0, V=1 */
807 h[0] = ( (sbit & 7) << 5 ) | ( (ebit & 7) << 2 ) | 1;
808 memmove(f->data.ptr, h, 4); /* copy the h261 header */
809 if (ebit) /* not aligned, restart from previous byte */
810 i--;
811 sbit = (8 - ebit) & 7;
812 ebit = 0;
813 if (!cur)
814 first = f;
815 cur = f;
816 }
817 if (cur)
818 cur->subclass |= 1; // RTP Marker
819
820 *tail = cur;
821 return first;
822}
struct sla_ringing_trunk * first
Definition: app_sla.c:332
static struct test_val d
static struct ast_frame * create_video_frame(uint8_t *start, uint8_t *end, int format, int head, struct ast_frame *prev)
Definition: vcodecs.c:228
#define H261_MIN_LEN

References AST_FORMAT_H261, b, create_video_frame(), d, ast_frame::data, first, H261_MIN_LEN, len(), NULL, ast_frame::ptr, and ast_frame::subclass.

◆ h263_decap()

static int h263_decap ( struct fbuf_t b,
uint8_t *  data,
int  len 
)
static

Definition at line 671 of file vcodecs.c.

672{
673 if (len < 4) {
674 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
675 return 1; /* error */
676 }
677
678 if ( (data[0] & 0x80) == 0) {
679 len -= 4;
680 data += 4;
681 } else {
682 ast_log(LOG_WARNING, "unsupported mode 0x%x\n",
683 data[0]);
684 return 1;
685 }
686 return fbuf_append(b, data, len, 0, 0); /* XXX no bit alignment support yet */
687}

References ast_log, b, ast_frame::data, fbuf_append(), len(), and LOG_WARNING.

◆ h263_enc_init()

static int h263_enc_init ( AVCodecContext *  enc_ctx)
static

Definition at line 530 of file vcodecs.c.

531{
532 /* XXX check whether these are supported */
533 enc_ctx->flags |= CODEC_FLAG_H263P_UMV;
534 enc_ctx->flags |= CODEC_FLAG_H263P_AIC;
535 enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
536 enc_ctx->flags |= CODEC_FLAG_AC_PRED;
537
538 return 0;
539}

◆ h263_encap()

static struct ast_frame * h263_encap ( struct fbuf_t b,
int  mtu,
struct ast_frame **  tail 
)
static

Definition at line 575 of file vcodecs.c.

577{
578 uint8_t *d = b->data;
579 int start = 0, i, len = b->used;
580 struct ast_frame *f, *cur = NULL, *first = NULL;
581 const int pheader_len = 4; /* Use RFC-2190 Mode A */
582 uint8_t h263_hdr[12]; /* worst case, room for a type c header */
583 uint8_t *h = h263_hdr; /* shorthand */
584
585#define H263_MIN_LEN 6
586 if (len < H263_MIN_LEN) /* unreasonably small */
587 return NULL;
588
589 memset(h263_hdr, '\0', sizeof(h263_hdr));
590 /* Now set the header bytes. Only type A by now,
591 * and h[0] = h[2] = h[3] = 0 by default.
592 * PTYPE starts 30 bits in the picture, so the first useful
593 * bit for us is bit 36 i.e. within d[4] (0 is the msbit).
594 * SRC = d[4] & 0x1c goes into data[1] & 0xe0
595 * I = d[4] & 0x02 goes into data[1] & 0x10
596 * U = d[4] & 0x01 goes into data[1] & 0x08
597 * S = d[5] & 0x80 goes into data[1] & 0x04
598 * A = d[5] & 0x40 goes into data[1] & 0x02
599 * R = 0 goes into data[1] & 0x01
600 * Optimizing it, we have
601 */
602 h[1] = ( (d[4] & 0x1f) << 3 ) | /* SRC, I, U */
603 ( (d[5] & 0xc0) >> 5 ); /* S, A, R */
604
605 /* now look for the next PSC or GOB header. First try to hit
606 * a '0' byte then look around for the 0000 0000 0000 0000 1 pattern
607 * which is both in the PSC and the GBSC.
608 */
609 for (i = H263_MIN_LEN, start = 0; start < len; start = i, i += 3) {
610 //ast_log(LOG_WARNING, "search at %d of %d/%d\n", i, start, len);
611 for (; i < len ; i++) {
612 uint8_t x, rpos, lpos;
613 int rpos_i; /* index corresponding to rpos */
614 if (d[i] != 0) /* cannot be in a GBSC */
615 continue;
616 if (i > len - 1)
617 break;
618 x = d[i+1];
619 if (x == 0) /* next is equally good */
620 continue;
621 /* see if around us we can make 16 '0' bits for the GBSC.
622 * Look for the first bit set on the right, and then
623 * see if we have enough 0 on the left.
624 * We are guaranteed to end before rpos == 0
625 */
626 for (rpos = 0x80, rpos_i = 8; rpos; rpos >>= 1, rpos_i--)
627 if (x & rpos) /* found the '1' bit in GBSC */
628 break;
629 x = d[i-1]; /* now look behind */
630 for (lpos = rpos; lpos ; lpos >>= 1)
631 if (x & lpos) /* too early, not a GBSC */
632 break;
633 if (lpos) /* as i said... */
634 continue;
635 /* now we have a GBSC starting somewhere in d[i-1],
636 * but it might be not byte-aligned
637 */
638 if (rpos == 0x80) { /* lucky case */
639 i = i - 1;
640 } else { /* XXX to be completed */
641 ast_log(LOG_WARNING, "unaligned GBSC 0x%x %d\n",
642 rpos, rpos_i);
643 }
644 break;
645 }
646 /* This frame is up to offset i (not inclusive).
647 * We do not split it yet even if larger than MTU.
648 */
649 f = create_video_frame(d + start, d+i, AST_FORMAT_H263,
650 pheader_len, cur);
651
652 if (!f)
653 break;
654 memmove(f->data.ptr, h, 4); /* copy the h263 header */
655 /* XXX to do: if not aligned, fix sbit and ebit,
656 * then move i back by 1 for the next frame
657 */
658 if (!cur)
659 first = f;
660 cur = f;
661 }
662
663 if (cur)
664 cur->subclass |= 1; // RTP Marker
665
666 *tail = cur;
667 return first;
668}
#define H263_MIN_LEN

References AST_FORMAT_H263, ast_log, b, create_video_frame(), d, ast_frame::data, first, H263_MIN_LEN, len(), LOG_WARNING, NULL, ast_frame::ptr, and ast_frame::subclass.

◆ h263p_decap()

static int h263p_decap ( struct fbuf_t b,
uint8_t *  data,
int  len 
)
static

extract the bitstream 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.

Definition at line 433 of file vcodecs.c.

434{
435 int PLEN;
436
437 if (len < 2) {
438 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
439 return 1;
440 }
441 PLEN = ( (data[0] & 1) << 5 ) | ( (data[1] & 0xf8) >> 3);
442
443 if (PLEN > 0) {
444 data += PLEN;
445 len -= PLEN;
446 }
447 if (data[0] & 4) /* bit P */
448 data[0] = data[1] = 0;
449 else {
450 data += 2;
451 len -= 2;
452 }
453 return fbuf_append(b, data, len, 0, 0); /* ignore trail bits */
454}

References ast_log, b, ast_frame::data, fbuf_append(), len(), and LOG_WARNING.

◆ h263p_enc_init()

static int h263p_enc_init ( AVCodecContext *  enc_ctx)
static

initialization of h263p

Definition at line 335 of file vcodecs.c.

336{
337 /* modes supported are
338 - Unrestricted Motion Vector (annex D)
339 - Advanced Prediction (annex F)
340 - Advanced Intra Coding (annex I)
341 - Deblocking Filter (annex J)
342 - Slice Structure (annex K)
343 - Alternative Inter VLC (annex S)
344 - Modified Quantization (annex T)
345 */
346 enc_ctx->flags |=CODEC_FLAG_H263P_UMV; /* annex D */
347 enc_ctx->flags |=CODEC_FLAG_AC_PRED; /* annex f ? */
348 enc_ctx->flags |=CODEC_FLAG_H263P_SLICE_STRUCT; /* annex k */
349 enc_ctx->flags |= CODEC_FLAG_H263P_AIC; /* annex I */
350
351 return 0;
352}

◆ h263p_encap()

static struct ast_frame * h263p_encap ( struct fbuf_t b,
int  mtu,
struct ast_frame **  tail 
)
static

Definition at line 360 of file vcodecs.c.

362{
363 struct ast_frame *cur = NULL, *first = NULL;
364 uint8_t *d = b->data;
365 int len = b->used;
366 int l = len; /* size of the current fragment. If 0, must look for a psc */
367
368 for (;len > 0; len -= l, d += l) {
369 uint8_t *data;
370 struct ast_frame *f;
371 int i, h;
372
373 if (len >= 3 && d[0] == 0 && d[1] == 0 && d[2] >= 0x80) {
374 /* we are starting a new block, so look for a PSC. */
375 for (i = 3; i < len - 3; i++) {
376 if (d[i] == 0 && d[i+1] == 0 && d[i+2] >= 0x80) {
377 l = i;
378 break;
379 }
380 }
381 }
382 if (l > mtu || l > len) { /* psc not found, split */
383 l = MIN(len, mtu);
384 }
385 if (l < 1 || l > mtu) {
386 ast_log(LOG_WARNING, "--- frame error l %d\n", l);
387 break;
388 }
389
390 if (d[0] == 0 && d[1] == 0) { /* we start with a psc */
391 h = 0;
392 } else { /* no psc, create a header */
393 h = 2;
394 }
395
396 f = create_video_frame(d, d+l, AST_FORMAT_H263_PLUS, h, cur);
397 if (!f)
398 break;
399
400 data = f->data.ptr;
401 if (h == 0) { /* we start with a psc */
402 data[0] |= 0x04; // set P == 1, and we are done
403 } else { /* no psc, create a header */
404 data[0] = data[1] = 0; // P == 0
405 }
406
407 if (!cur)
408 first = f;
409 cur = f;
410 }
411
412 if (cur)
413 cur->subclass |= 1; // RTP Marker
414
415 *tail = cur; /* end of the list */
416 return first;
417}
#define MIN(a, b)
Definition: utils.h:231

References ast_log, b, create_video_frame(), d, ast_frame::data, first, len(), LOG_WARNING, MIN, NULL, ast_frame::ptr, and ast_frame::subclass.

◆ h264_dec_init()

static int h264_dec_init ( AVCodecContext *  dec_ctx)
static

Definition at line 938 of file vcodecs.c.

939{
940 dec_ctx->flags |= CODEC_FLAG_TRUNCATED;
941
942 return 0;
943}

◆ h264_decap()

static int h264_decap ( struct fbuf_t b,
uint8_t *  data,
int  len 
)
static

Definition at line 1046 of file vcodecs.c.

1047{
1048 /* Start Code Prefix (Annex B in specification) */
1049 uint8_t scp[] = { 0x00, 0x00, 0x00, 0x01 };
1050 int retval = 0;
1051 int type, ofs = 0;
1052
1053 if (len < 2) {
1054 ast_log(LOG_WARNING, "--- invalid len %d\n", len);
1055 return 1;
1056 }
1057 /* first of all, check if the packet has F == 0 */
1058 if (data[0] & 0x80) {
1059 ast_log(LOG_WARNING, "--- forbidden packet; nal: %02hhx\n",
1060 data[0]);
1061 return 1;
1062 }
1063
1064 type = data[0] & 0x1f;
1065 switch (type) {
1066 case 0:
1067 case 31:
1068 ast_log(LOG_WARNING, "--- invalid type: %d\n", type);
1069 return 1;
1070 case 24:
1071 case 25:
1072 case 26:
1073 case 27:
1074 case 29:
1075 ast_log(LOG_WARNING, "--- encapsulation not supported : %d\n", type);
1076 return 1;
1077 case 28: /* FU-A Unit */
1078 if (data[1] & 0x80) { // S == 1, import F and NRI from next
1079 data[1] &= 0x1f; /* preserve type */
1080 data[1] |= (data[0] & 0xe0); /* import F & NRI */
1081 retval = fbuf_append(b, scp, sizeof(scp), 0, 0);
1082 ofs = 1;
1083 } else {
1084 ofs = 2;
1085 }
1086 break;
1087 default: /* From 1 to 23 (Single NAL Unit) */
1088 retval = fbuf_append(b, scp, sizeof(scp), 0, 0);
1089 }
1090 if (!retval)
1091 retval = fbuf_append(b, data + ofs, len - ofs, 0, 0);
1092 if (retval)
1093 ast_log(LOG_WARNING, "result %d\n", retval);
1094 return retval;
1095}
static const char type[]
Definition: chan_ooh323.c:109
static ENTRY retval
Definition: hsearch.c:50

References ast_log, b, ast_frame::data, fbuf_append(), len(), LOG_WARNING, retval, and type.

◆ h264_enc_init()

static int h264_enc_init ( AVCodecContext *  enc_ctx)
static

Definition at line 926 of file vcodecs.c.

927{
928 enc_ctx->flags |= CODEC_FLAG_TRUNCATED;
929 //enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
930 //enc_ctx->flags2 |= CODEC_FLAG2_FASTPSKIP;
931 /* TODO: Maybe we need to add some other flags */
932 enc_ctx->rtp_mode = 0;
933 enc_ctx->rtp_payload_size = 0;
934 enc_ctx->bit_rate_tolerance = enc_ctx->bit_rate;
935 return 0;
936}

◆ h264_encap()

static struct ast_frame * h264_encap ( struct fbuf_t b,
int  mtu,
struct ast_frame **  tail 
)
static

Definition at line 959 of file vcodecs.c.

961{
962 struct ast_frame *f = NULL, *cur = NULL, *first = NULL;
963 uint8_t *d, *start = b->data;
964 uint8_t *end = start + b->used;
965
966 /* Search the first start code prefix - ITU-T H.264 sec. B.2,
967 * and move start right after that, on the NAL header byte.
968 */
969#define HAVE_NAL(x) (x[-4] == 0 && x[-3] == 0 && x[-2] == 0 && x[-1] == 1)
970 for (start += 4; start < end; start++) {
971 int ty = start[0] & 0x1f;
972 if (HAVE_NAL(start) && ty != 0 && ty != 31)
973 break;
974 }
975 /* if not found, or too short, we just skip the next loop and are done. */
976
977 /* Here follows the main loop to create frames. Search subsequent start
978 * codes, and then possibly fragment the unit into smaller fragments.
979 */
980 for (;start < end - 4; start = d) {
981 int size; /* size of current block */
982 uint8_t hdr[2]; /* add-on header when fragmenting */
983 int ty = 0;
984
985 /* now search next nal */
986 for (d = start + 4; d < end; d++) {
987 ty = d[0] & 0x1f;
988 if (HAVE_NAL(d))
989 break; /* found NAL */
990 }
991 /* have a block to send. d past the start code unless we overflow */
992 if (d >= end) { /* NAL not found */
993 d = end + 4;
994 } else if (ty == 0 || ty == 31) { /* found but invalid type, skip */
995 ast_log(LOG_WARNING, "skip invalid nal type %d at %d of %d\n",
996 ty, d - (uint8_t *)b->data, b->used);
997 continue;
998 }
999
1000 size = d - start - 4; /* don't count the end */
1001
1002 if (size < mtu) { // test - don't fragment
1003 // Single NAL Unit
1004 f = create_video_frame(start, d - 4, AST_FORMAT_H264, 0, cur);
1005 if (!f)
1006 break;
1007 if (!first)
1008 first = f;
1009
1010 cur = f;
1011 continue;
1012 }
1013
1014 // Fragmented Unit (Mode A: no DON, very weak)
1015 hdr[0] = (*start & 0xe0) | 28; /* mark as a fragmentation unit */
1016 hdr[1] = (*start++ & 0x1f) | 0x80 ; /* keep type and set START bit */
1017 size--; /* skip the NAL header */
1018 while (size) {
1019 uint8_t *data;
1020 int frag_size = MIN(size, mtu);
1021
1022 f = create_video_frame(start, start+frag_size, AST_FORMAT_H264, 2, cur);
1023 if (!f)
1024 break;
1025 size -= frag_size; /* skip this data block */
1026 start += frag_size;
1027
1028 data = f->data.ptr;
1029 data[0] = hdr[0];
1030 data[1] = hdr[1] | (size == 0 ? 0x40 : 0); /* end bit if we are done */
1031 hdr[1] &= ~0x80; /* clear start bit for subsequent frames */
1032 if (!first)
1033 first = f;
1034 cur = f;
1035 }
1036 }
1037
1038 if (cur)
1039 cur->subclass |= 1; // RTP Marker
1040
1041 *tail = cur;
1042
1043 return first;
1044}
#define HAVE_NAL(x)

References AST_FORMAT_H264, ast_log, b, create_video_frame(), d, ast_frame::data, end, first, HAVE_NAL, LOG_WARNING, MIN, NULL, ast_frame::ptr, and ast_frame::subclass.

◆ map_video_codec()

static struct video_codec_desc * map_video_codec ( int  fmt)
static

Definition at line 1158 of file vcodecs.c.

1159{
1160 int i;
1161
1162 for (i = 0; supported_codecs[i]; i++)
1163 if (fmt == supported_codecs[i]->format) {
1164 ast_log(LOG_WARNING, "using %s for format 0x%x\n",
1165 supported_codecs[i]->name, fmt);
1166 return supported_codecs[i];
1167 }
1168 return NULL;
1169}
static const char name[]
Definition: format_mp3.c:68
static const struct video_codec_desc * supported_codecs[]
Definition: vcodecs.c:1145

References ast_log, video_codec_desc::format, LOG_WARNING, name, NULL, and supported_codecs.

Referenced by dec_init().

◆ map_video_format()

static enum CodecID map_video_format ( uint32_t  ast_format,
int  rw 
)
static

map an asterisk format into an ffmpeg one

Definition at line 1133 of file vcodecs.c.

1134{
1135 struct _cm *i;
1136
1137 for (i = video_formats; i->ast_format != 0; i++)
1138 if (ast_format & i->ast_format && rw & i->rw) {
1139 return i->codec;
1140 }
1141 return CODEC_ID_NONE;
1142}
Definition: vcodecs.c:1113
enum _cm::@144 rw
uint32_t ast_format
Definition: vcodecs.c:1114
enum CodecID codec
Definition: vcodecs.c:1115
Definition of a media format.
Definition: format.c:43
static const struct _cm video_formats[]
Definition: vcodecs.c:1120

References _cm::ast_format, _cm::codec, _cm::rw, and video_formats.

Referenced by dec_init().

◆ mpeg4_decap()

static int mpeg4_decap ( struct fbuf_t b,
uint8_t *  data,
int  len 
)
static

Definition at line 893 of file vcodecs.c.

894{
895 return fbuf_append(b, data, len, 0, 0);
896}

References b, ast_frame::data, fbuf_append(), and len().

◆ mpeg4_decode()

static int mpeg4_decode ( struct video_dec_desc v,
struct fbuf_t b 
)
static

Definition at line 898 of file vcodecs.c.

899{
900 int full_frame = 0, datalen = b->used;
901 int ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame,
902 b->data, datalen);
903 if (ret < 0) {
904 ast_log(LOG_NOTICE, "Error decoding\n");
905 ret = datalen; /* assume we used everything. */
906 }
907 datalen -= ret;
908 if (datalen > 0) /* update b with leftover bytes */
909 memmove(b->data, b->data + ret, datalen);
910 b->used = datalen;
911 b->ebit = 0;
912 return full_frame;
913}

References ast_log, b, video_dec_desc::d_frame, ast_frame::datalen, video_dec_desc::dec_ctx, and LOG_NOTICE.

◆ mpeg4_enc_init()

static int mpeg4_enc_init ( AVCodecContext *  enc_ctx)
static

Definition at line 854 of file vcodecs.c.

855{
856#if 0
857 //enc_ctx->flags |= CODEC_FLAG_LOW_DELAY; /*don't use b frames ?*/
858 enc_ctx->flags |= CODEC_FLAG_AC_PRED;
859 enc_ctx->flags |= CODEC_FLAG_H263P_UMV;
860 enc_ctx->flags |= CODEC_FLAG_QPEL;
861 enc_ctx->flags |= CODEC_FLAG_4MV;
862 enc_ctx->flags |= CODEC_FLAG_GMC;
863 enc_ctx->flags |= CODEC_FLAG_LOOP_FILTER;
864 enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
865#endif
866 enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */
867 return 0;
868}

◆ mpeg4_encap()

static struct ast_frame * mpeg4_encap ( struct fbuf_t b,
int  mtu,
struct ast_frame **  tail 
)
static

Definition at line 871 of file vcodecs.c.

873{
874 struct ast_frame *f, *cur = NULL, *first = NULL;
875 uint8_t *d = b->data;
876 uint8_t *end = d + b->used;
877 int len;
878
879 for (;d < end; d += len, cur = f) {
880 len = MIN(mtu, end - d);
881 f = create_video_frame(d, d + len, AST_FORMAT_MP4_VIDEO, 0, cur);
882 if (!f)
883 break;
884 if (!first)
885 first = f;
886 }
887 if (cur)
888 cur->subclass |= 1;
889 *tail = cur;
890 return first;
891}

References b, create_video_frame(), d, end, first, len(), MIN, NULL, and ast_frame::subclass.

Variable Documentation

◆ h261_codec

struct video_codec_desc h261_codec
static

Definition at line 842 of file vcodecs.c.

◆ h263_codec

struct video_codec_desc h263_codec
static

Definition at line 689 of file vcodecs.c.

◆ h263p_codec

struct video_codec_desc h263p_codec
static

Definition at line 517 of file vcodecs.c.

◆ h264_codec

struct video_codec_desc h264_codec
static

Definition at line 1097 of file vcodecs.c.

◆ mpeg4_codec

struct video_codec_desc mpeg4_codec
static

Definition at line 915 of file vcodecs.c.

◆ supported_codecs

const struct video_codec_desc* supported_codecs[]
static

Definition at line 1145 of file vcodecs.c.

Referenced by map_video_codec().

◆ video_formats

const struct _cm video_formats[]
static

Definition at line 1120 of file vcodecs.c.

Referenced by map_video_format().