support sdl_videodriver to send output to x11/aalib/console
[asterisk/asterisk.git] / channels / console_video.c
1 /*
2  * Experimental support for video sessions. We use SDL for rendering, ffmpeg
3  * as the codec library for encoding and decoding, and Video4Linux and X11
4  * to generate the local video stream.
5  *
6  * If one of these pieces is not available, either at compile time or at
7  * runtime, we do our best to run without it. Of course, no codec library
8  * means we can only deal with raw data, no SDL means we cannot do rendering,
9  * no V4L or X11 means we cannot generate data (but in principle we could
10  * stream from or record to a file).
11  *
12  * We need a recent (2007.07.12 or newer) version of ffmpeg to avoid warnings.
13  * Older versions might give 'deprecated' messages during compilation,
14  * thus not compiling in AST_DEVMODE, or don't have swscale, in which case
15  * you can try to compile #defining OLD_FFMPEG here.
16  *
17  * $Revision$
18  */
19
20 //#define DROP_PACKETS 5       /* if set, drop this % of video packets */
21 //#define OLD_FFMPEG    1       /* set for old ffmpeg with no swscale */
22
23 #include "asterisk.h"
24 #include <sys/ioctl.h>
25 #include <math.h>       /* sqrt */
26 #include "asterisk/cli.h"
27 #include "asterisk/file.h"
28 #include "asterisk/channel.h"
29
30 #include "console_video.h"
31
32 /*
33 The code is structured as follows.
34
35 When a new console channel is created, we call console_video_start()
36 to initialize SDL, the source, and the encoder/ decoder for the
37 formats in use (XXX the latter two should be done later, once the
38 codec negotiation is complete).  Also, a thread is created to handle
39 the video source and generate frames.
40
41 While communication is on, the local source is generated by the
42 video thread, which wakes up periodically, generates frames and
43 enqueues them in chan->readq.  Incoming rtp frames are passed to
44 console_write_video(), decoded and passed to SDL for display.
45
46 For as unfortunate and confusing as it can be, we need to deal with a
47 number of different video representations (size, codec/pixel format,
48 codec parameters), as follows:
49
50  loc_src        is the data coming from the camera/X11/etc.
51         The format is typically constrained by the video source.
52
53  enc_in         is the input required by the encoder.
54         Typically constrained in size by the encoder type.
55
56  enc_out        is the bitstream transmitted over RTP.
57         Typically negotiated while the call is established.
58
59  loc_dpy        is the format used to display the local video source.
60         Depending on user preferences this can have the same size as
61         loc_src_fmt, or enc_in_fmt, or thumbnail size (e.g. PiP output)
62
63  dec_in         is the incoming RTP bitstream. Negotiated
64         during call establishment, it is not necessarily the same as
65         enc_in_fmt
66
67  dec_out        the output of the decoder.
68         The format is whatever the other side sends, and the
69         buffer is allocated by avcodec_decode_... so we only
70         copy the data here.
71
72  rem_dpy        the format used to display the remote stream
73
74 We store the format info together with the buffer storing the data.
75 As a future optimization, a format/buffer may reference another one
76 if the formats are equivalent. This will save some unnecessary format
77 conversion.
78
79
80 In order to handle video you need to add to sip.conf (and presumably
81 iax.conf too) the following:
82
83         [general](+)
84                 videosupport=yes
85                 allow=h263      ; this or other video formats
86                 allow=h263p     ; this or other video formats
87
88  */
89
90 /*
91  * Codecs are absolutely necessary or we cannot do anything.
92  * In principle SDL is optional too (used for rendering only, but we
93  * could still source data withouth it), however at the moment it is required.
94  */
95 #if !defined(HAVE_VIDEO_CONSOLE) || !defined(HAVE_FFMPEG) || !defined(HAVE_SDL)
96 /* stubs if required pieces are missing */
97 int console_write_video(struct ast_channel *chan, struct ast_frame *f)
98 {
99         return 0;       /* writing video not supported */
100 }
101
102 int console_video_cli(struct video_desc *env, const char *var, int fd)
103 {
104         return 1;       /* nothing matched */
105 }
106
107 int console_video_config(struct video_desc **penv, const char *var, const char *val)
108 {
109         return 1;       /* no configuration */
110 }
111
112 void console_video_start(struct video_desc *env, struct ast_channel *owner)
113 {
114         ast_log(LOG_WARNING, "console video support not present\n");
115 }
116
117 void console_video_uninit(struct video_desc *env)
118 {
119 }
120
121 int console_video_formats = 0;
122
123 #else /* defined(HAVE_FFMPEG) && defined(HAVE_SDL) */
124
125 /*! The list of video formats we support. */
126 int console_video_formats = 
127         AST_FORMAT_H263_PLUS | AST_FORMAT_H263 |
128         AST_FORMAT_MP4_VIDEO | AST_FORMAT_H264 | AST_FORMAT_H261 ;
129
130 #ifdef HAVE_X11
131 #include <X11/Xlib.h>           /* this should be conditional */
132 #endif
133
134 #include <ffmpeg/avcodec.h>
135 #ifndef OLD_FFMPEG
136 #include <ffmpeg/swscale.h>     /* requires a recent ffmpeg */
137 #endif
138
139 #include <SDL/SDL.h>
140 #ifdef HAVE_SDL_IMAGE
141 #include <SDL/SDL_image.h>      /* for loading images */
142 #endif
143 #ifdef HAVE_SDL_TTF
144 #include <SDL/SDL_ttf.h>        /* render text on sdl surfaces */
145 #endif
146
147 /*
148  * In many places we use buffers to store the raw frames (but not only),
149  * so here is a structure to keep all the info. data = NULL means the
150  * structure is not initialized, so the other fields are invalid.
151  * size = 0 means the buffer is not malloc'ed so we don't have to free it.
152  */
153 struct fbuf_t {         /* frame buffers, dynamically allocated */
154         uint8_t *data;  /* memory, malloced if size > 0, just reference
155                          * otherwise */
156         int     size;   /* total size in bytes */
157         int     used;   /* space used so far */
158         int     ebit;   /* bits to ignore at the end */
159         int     x;      /* origin, if necessary */
160         int     y;
161         int     w;      /* size */ 
162         int     h;
163         int     pix_fmt;
164 };
165
166 struct video_codec_desc;        /* forward declaration */
167 /*
168  * Descriptor of the local source, made of the following pieces:
169  *  + configuration info (geometry, device name, fps...). These are read
170  *    from the config file and copied here before calling video_out_init();
171  *  + the frame buffer (buf) and source pixel format, allocated at init time;
172  *  + the encoding and RTP info, including timestamps to generate
173  *    frames at the correct rate;
174  *  + source-specific info, i.e. fd for /dev/video, dpy-image for x11, etc,
175  *    filled in by video_open
176  * NOTE: loc_src.data == NULL means the rest of the struct is invalid, and
177  *      the video source is not available.
178  */
179 struct video_out_desc {
180         /* video device support.
181          * videodevice and geometry are read from the config file.
182          * At the right time we try to open it and allocate a buffer.
183          * If we are successful, webcam_bufsize > 0 and we can read.
184          */
185         /* all the following is config file info copied from the parent */
186         char            videodevice[64];
187         int             fps;
188         int             bitrate;
189         int             qmin;
190
191         int sendvideo;
192
193         struct fbuf_t   loc_src;        /* local source buffer, allocated in video_open() */
194         struct fbuf_t   enc_in;         /* encoder input buffer, allocated in video_out_init() */
195         struct fbuf_t   enc_out;        /* encoder output buffer, allocated in video_out_init() */
196         struct fbuf_t   loc_dpy;        /* display source buffer, no buffer (managed by SDL in bmp[1]) */
197         struct fbuf_t   keypad_dpy;     /* keypad source buffer, XXX */
198
199         struct video_codec_desc *enc;   /* encoder */
200         AVCodecContext  *enc_ctx;       /* encoding context */
201         AVCodec         *codec;
202         AVFrame         *frame; /* The initial part is an AVPicture */
203         int             mtu;
204         struct timeval  last_frame;     /* when we read the last frame ? */
205
206         /* device specific info */
207         int             fd;             /* file descriptor, for webcam */
208 #ifdef HAVE_X11
209         Display         *dpy;                   /* x11 grabber info */
210         XImage          *image;
211         int             screen_width;   /* width of X screen */
212         int             screen_height;  /* height of X screen */
213 #endif
214 };
215
216 /*
217  * Descriptor for the incoming stream, with a buffer for the bitstream
218  * extracted by the RTP packets, RTP reassembly info, and a frame buffer
219  * for the decoded frame (buf).
220  * and store the result in a suitable frame buffer for later display.
221  * NOTE: dec_ctx == NULL means the rest is invalid (e.g. because no
222  *      codec, no memory, etc.) and we must drop all incoming frames.
223  *
224  * Incoming payload is stored in one of the dec_in[] buffers, which are
225  * emptied by the video thread. These buffers are organized in a circular
226  * queue, with dec_in_cur being the buffer in use by the incoming stream,
227  * and dec_in_dpy is the one being displayed. When the pointers need to
228  * be changed, we synchronize the access to them with dec_in_lock.
229  * When the list is full dec_in_cur = NULL (we cannot store new data),
230  * when the list is empty dec_in_dpy is NULL (we cannot display frames).
231  */
232 struct video_in_desc {
233         struct video_codec_desc *dec;   /* decoder */
234         AVCodecContext          *dec_ctx;       /* information about the codec in the stream */
235         AVCodec                 *codec;         /* reference to the codec */
236         AVFrame                 *d_frame;       /* place to store the decoded frame */
237         AVCodecParserContext    *parser;
238         uint16_t                next_seq;       /* must be 16 bit */
239         int                     discard;        /* flag for discard status */
240 #define N_DEC_IN        3       /* number of incoming buffers */
241         struct fbuf_t           *dec_in_cur;    /* buffer being filled in */
242         struct fbuf_t           *dec_in_dpy;    /* buffer to display */
243         ast_mutex_t             dec_in_lock;
244         struct fbuf_t dec_in[N_DEC_IN]; /* incoming bitstream, allocated/extended in fbuf_append() */
245         struct fbuf_t dec_out;  /* decoded frame, no buffer (data is in AVFrame) */
246         struct fbuf_t rem_dpy;  /* display remote image, no buffer (it is in win[WIN_REMOTE].bmp) */
247 };
248
249 /*
250  * Each codec is defined by a number of callbacks
251  */
252 /*! \brief initialize the encoder */
253 typedef int (*encoder_init_f)(struct video_out_desc *v);
254
255 /*! \brief actually call the encoder */
256 typedef int (*encoder_encode_f)(struct video_out_desc *v);
257
258 /*! \brief encapsulate the bistream in RTP frames */
259 typedef struct ast_frame *(*encoder_encap_f)(struct video_out_desc *out,
260                 struct ast_frame **tail);
261
262 /*! \brief inizialize the decoder */
263 typedef int (*decoder_init_f)(struct video_in_desc *v);
264
265 /*! \brief extract the bitstream from RTP frames and store in the fbuf.
266  * return 0 if ok, 1 on error
267  */
268 typedef int (*decoder_decap_f)(struct fbuf_t *b, uint8_t *data, int len);
269
270 /*! \brief actually call the decoder */
271 typedef int (*decoder_decode_f)(struct video_in_desc *v, struct fbuf_t *b);
272
273 struct video_codec_desc {
274         const char              *name;          /* format name */
275         int                     format;         /* AST_FORMAT_* */
276         encoder_init_f          enc_init;
277         encoder_encap_f         enc_encap;
278         encoder_encode_f        enc_run;
279         decoder_init_f          dec_init;
280         decoder_decap_f         dec_decap;
281         decoder_decode_f        dec_run;
282 };
283
284 /* our representation of a displayed window. SDL can only do one main
285  * window so we map everything within that one
286  */
287 enum { WIN_LOCAL, WIN_REMOTE, WIN_KEYPAD, WIN_MAX };
288
289 struct display_window   {
290         SDL_Overlay             *bmp;
291         SDL_Rect                rect;   /* loc. of images */
292 };
293
294 #define GUI_BUFFER_LEN 256                      /* buffer lenght used for input buffers */
295
296 enum kp_type { KP_NONE, KP_RECT, KP_CIRCLE };
297 struct keypad_entry {
298         int c;  /* corresponding character */
299         int x0, y0, x1, y1, h;  /* arguments */
300         enum kp_type type;
301 };
302
303 /*! \brief info related to the gui: button status, mouse coords, etc. */
304 struct gui_info {
305         char                    inbuf[GUI_BUFFER_LEN];  /* buffer for to-dial buffer */
306         int                     inbuf_pos;      /* next free position in inbuf */
307         char                    msgbuf[GUI_BUFFER_LEN]; /* buffer for text-message buffer */
308         int                     msgbuf_pos;     /* next free position in msgbuf */
309         int                     text_mode;      /* switch to-dial and text-message mode */
310         int                     drag_mode;      /* switch phone and drag-source mode */
311         int                     x_drag;         /* x coordinate where the drag starts */
312         int                     y_drag;         /* y coordinate where the drag starts */
313 #ifdef HAVE_SDL_TTF
314         TTF_Font                *font;          /* font to be used */ 
315 #endif
316         int                     outfd;          /* fd for output */
317         SDL_Surface             *keypad;        /* the pixmap for the keypad */
318         int kp_size, kp_used;
319         struct keypad_entry *kp;
320 };
321
322 /*
323  * The overall descriptor, with room for config info, video source and
324  * received data descriptors, SDL info, etc.
325  */
326 struct video_desc {
327         char                    codec_name[64]; /* the codec we use */
328
329         pthread_t               vthread;        /* video thread */
330         int                     shutdown;       /* set to shutdown vthread */
331         struct ast_channel      *owner;         /* owner channel */
332
333         struct video_in_desc    in;             /* remote video descriptor */
334         struct video_out_desc   out;            /* local video descriptor */
335
336         struct gui_info         gui;
337
338         /* support for display. */
339         int                     sdl_ok;
340         int                     gui_ok;
341         SDL_Surface             *screen;        /* the main window */
342         char                    keypad_file[256];       /* image for the keypad */
343         char                    keypad_font[256];       /* font for the keypad */
344
345         char                    sdl_videodriver[256];
346         struct display_window   win[WIN_MAX];
347 };
348
349 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p);
350
351 static void fbuf_free(struct fbuf_t *b)
352 {
353         struct fbuf_t x = *b;
354
355         if (b->data && b->size)
356                 ast_free(b->data);
357         bzero(b, sizeof(*b));
358         /* restore some fields */
359         b->w = x.w;
360         b->h = x.h;
361         b->pix_fmt = x.pix_fmt;
362 }
363
364 /*
365  * Append a chunk of data to a buffer taking care of bit alignment
366  * Return 0 on success, != 0 on failure
367  */
368 static int fbuf_append(struct fbuf_t *b, uint8_t *src, int len,
369         int sbit, int ebit)
370 {
371         /*
372          * Allocate buffer. ffmpeg wants an extra FF_INPUT_BUFFER_PADDING_SIZE,
373          * and also wants 0 as a buffer terminator to prevent trouble.
374          */
375         int need = len + FF_INPUT_BUFFER_PADDING_SIZE;
376         int i;
377         uint8_t *dst, mask;
378
379         if (b->data == NULL) {
380                 b->size = need;
381                 b->used = 0;
382                 b->ebit = 0;
383                 b->data = ast_calloc(1, b->size);
384         } else if (b->used + need > b->size) {
385                 b->size = b->used + need;
386                 b->data = ast_realloc(b->data, b->size);
387         }
388         if (b->data == NULL) {
389                 ast_log(LOG_WARNING, "alloc failure for %d, discard\n",
390                         b->size);
391                 return 1;
392         }
393         if (b->used == 0 && b->ebit != 0) {
394                 ast_log(LOG_WARNING, "ebit not reset at start\n");
395                 b->ebit = 0;
396         }
397         dst = b->data + b->used;
398         i = b->ebit + sbit;     /* bits to ignore around */
399         if (i == 0) {   /* easy case, just append */
400                 /* do everything in the common block */
401         } else if (i == 8) { /* easy too, just handle the overlap byte */
402                 mask = (1 << b->ebit) - 1;
403                 /* update the last byte in the buffer */
404                 dst[-1] &= ~mask;       /* clear bits to ignore */
405                 dst[-1] |= (*src & mask);       /* append new bits */
406                 src += 1;       /* skip and prepare for common block */
407                 len --;
408         } else {        /* must shift the new block, not done yet */
409                 ast_log(LOG_WARNING, "must handle shift %d %d at %d\n",
410                         b->ebit, sbit, b->used);
411                 return 1;
412         }
413         memcpy(dst, src, len);
414         b->used += len;
415         b->ebit = ebit;
416         b->data[b->used] = 0;   /* padding */
417         return 0;
418 }
419
420 /*!
421  * Build an ast_frame for a given chunk of data, and link it into
422  * the queue, with possibly 'head' bytes at the beginning to
423  * fill in some fields later.
424  */
425 static struct ast_frame *create_video_frame(uint8_t *start, uint8_t *end,
426                        int format, int head, struct ast_frame *prev)
427 {
428         int len = end-start;
429         uint8_t *data;
430         struct ast_frame *f;
431
432         data = ast_calloc(1, len+head);
433         f = ast_calloc(1, sizeof(*f));
434         if (f == NULL || data == NULL) {
435                 ast_log(LOG_WARNING, "--- frame error f %p data %p len %d format %d\n",
436                                 f, data, len, format);
437                 if (f)
438                         ast_free(f);
439                 if (data)
440                         ast_free(data);
441                 return NULL;
442         }
443         memcpy(data+head, start, len);
444         f->data = data;
445         f->mallocd = AST_MALLOCD_DATA | AST_MALLOCD_HDR;
446         //f->has_timing_info = 1;
447         //f->ts = ast_tvdiff_ms(ast_tvnow(), out->ts);
448         f->datalen = len+head;
449         f->frametype = AST_FRAME_VIDEO;
450         f->subclass = format;
451         f->samples = 0;
452         f->offset = 0;
453         f->src = "Console";
454         f->delivery.tv_sec = 0;
455         f->delivery.tv_usec = 0;
456         f->seqno = 0;
457         AST_LIST_NEXT(f, frame_list) = NULL;
458
459         if (prev)
460                 AST_LIST_NEXT(prev, frame_list) = f;
461
462         return f;
463 }
464
465 /* some debugging code to check the bitstream:
466  * declare a bit buffer, initialize it, and fetch data from it.
467  */
468 struct bitbuf {
469         const uint8_t *base;
470         int     bitsize;        /* total size in bits */
471         int     ofs;    /* next bit to read */
472 };
473
474 static struct bitbuf bitbuf_init(const uint8_t *base, int bitsize, int start_ofs)
475 {
476         struct bitbuf a;
477         a.base = base;
478         a.bitsize = bitsize;
479         a.ofs = start_ofs;
480         return a;
481 }
482
483 static int bitbuf_left(struct bitbuf *b)
484 {
485         return b->bitsize - b->ofs;
486 }
487
488 static uint32_t getbits(struct bitbuf *b, int n)
489 {
490         int i, ofs;
491         const uint8_t *d;
492         uint8_t mask;
493         uint32_t retval = 0;
494         if (n> 31) {
495                 ast_log(LOG_WARNING, "too many bits %d, max 32\n", n);
496                 return 0;
497         }
498         if (n + b->ofs > b->bitsize) {
499                 ast_log(LOG_WARNING, "bitbuf overflow %d of %d\n", n + b->ofs, b->bitsize);
500                 n = b->bitsize - b->ofs;
501         }
502         ofs = 7 - b->ofs % 8;   /* start from msb */
503         mask = 1 << ofs;
504         d = b->base + b->ofs / 8;       /* current byte */
505         for (i=0 ; i < n; i++) {
506                 retval += retval + (*d & mask ? 1 : 0); /* shift in new byte */
507                 b->ofs++;
508                 mask >>= 1;
509                 if (mask == 0) {
510                         d++;
511                         mask = 0x80;
512                 }
513         }
514         return retval;
515 }
516
517 static void check_h261(struct fbuf_t *b)
518 {
519         struct bitbuf a = bitbuf_init(b->data, b->used * 8, 0);
520         uint32_t x, y;
521         
522         x = getbits(&a, 20);    /* PSC, 0000 0000 0000 0001 0000 */
523         if (x != 0x10) {
524                 ast_log(LOG_WARNING, "bad PSC 0x%x\n", x);
525                 return;
526         }
527         x = getbits(&a, 5);     /* temporal reference */
528         y = getbits(&a, 6);     /* ptype */
529         if (0)
530         ast_log(LOG_WARNING, "size %d TR %d PTY spl %d doc %d freeze %d %sCIF hi %d\n",
531                 b->used,
532                 x,
533                 (y & 0x20) ? 1 : 0,
534                 (y & 0x10) ? 1 : 0,
535                 (y & 0x8) ? 1 : 0,
536                 (y & 0x4) ? "" : "Q",
537                 (y & 0x2) ? 1:0);
538         while ( (x = getbits(&a, 1)) == 1)
539                 ast_log(LOG_WARNING, "PSPARE 0x%x\n", getbits(&a, 8));
540         // ast_log(LOG_WARNING, "PSPARE 0 - start GOB LAYER\n");
541         while ( (x = bitbuf_left(&a)) > 0) {
542                 // ast_log(LOG_WARNING, "GBSC %d bits left\n", x);
543                 x = getbits(&a, 16); /* GBSC 0000 0000 0000 0001 */
544                 if (x != 0x1) {
545                         ast_log(LOG_WARNING, "bad GBSC 0x%x\n", x);
546                         break;
547                 }
548                 x = getbits(&a, 4);     /* group number */
549                 y = getbits(&a, 5);     /* gquant */
550                 if (x == 0) {
551                         ast_log(LOG_WARNING, "  bad GN %d\n", x);
552                         break;
553                 }
554                 while ( (x = getbits(&a, 1)) == 1)
555                         ast_log(LOG_WARNING, "GSPARE 0x%x\n", getbits(&a, 8));
556                 while ( (x = bitbuf_left(&a)) > 0) { /* MB layer */
557                         break;
558                 }
559         }
560 }
561
562 void dump_buf(struct fbuf_t *b);
563 void dump_buf(struct fbuf_t *b)
564 {
565         int i, x, last2lines;
566         char buf[80];
567
568         last2lines = (b->used - 16) & ~0xf;
569         ast_log(LOG_WARNING, "buf size %d of %d\n", b->used, b->size);
570         for (i = 0; i < b->used; i++) {
571                 x = i & 0xf;
572                 if ( x == 0) {  /* new line */
573                         if (i != 0)
574                                 ast_log(LOG_WARNING, "%s\n", buf);
575                         bzero(buf, sizeof(buf));
576                         sprintf(buf, "%04x: ", i);
577                 }
578                 sprintf(buf + 6 + x*3, "%02x ", b->data[i]);
579                 if (i > 31 && i < last2lines)
580                         i = last2lines - 1;
581         }
582         if (buf[0])
583                 ast_log(LOG_WARNING, "%s\n", buf);
584 }
585 /*
586  * Here starts the glue code for the various supported video codecs.
587  * For each of them, we need to provide routines for initialization,
588  * calling the encoder, encapsulating the bitstream in ast_frames,
589  * extracting payload from ast_frames, and calling the decoder.
590  */
591
592 /*--- h263+ support --- */
593
594 /*! \brief initialization of h263p */
595 static int h263p_enc_init(struct video_out_desc *v)
596 {
597         /* modes supported are
598         - Unrestricted Motion Vector (annex D)
599         - Advanced Prediction (annex F)
600         - Advanced Intra Coding (annex I)
601         - Deblocking Filter (annex J)
602         - Slice Structure (annex K)
603         - Alternative Inter VLC (annex S)
604         - Modified Quantization (annex T)
605         */
606         v->enc_ctx->flags |=CODEC_FLAG_H263P_UMV; /* annex D */
607         v->enc_ctx->flags |=CODEC_FLAG_AC_PRED; /* annex f ? */
608         v->enc_ctx->flags |=CODEC_FLAG_H263P_SLICE_STRUCT; /* annex k */
609         v->enc_ctx->flags |= CODEC_FLAG_H263P_AIC; /* annex I */
610
611         v->enc_ctx->gop_size = v->fps*5; // emit I frame every 5 seconds
612         return 0;
613 }
614
615
616 /*
617  * Create RTP/H.263 fragments to avoid IP fragmentation. We fragment on a
618  * PSC or a GBSC, but if we don't find a suitable place just break somewhere.
619  * Everything is byte-aligned.
620  */
621 static struct ast_frame *h263p_encap(struct video_out_desc *out,
622         struct ast_frame **tail)
623 {
624         struct ast_frame *cur = NULL, *first = NULL;
625         uint8_t *d = out->enc_out.data;
626         int len = out->enc_out.used;
627         int l = len; /* size of the current fragment. If 0, must look for a psc */
628
629         for (;len > 0; len -= l, d += l) {
630                 uint8_t *data;
631                 struct ast_frame *f;
632                 int i, h;
633
634                 if (len >= 3 && d[0] == 0 && d[1] == 0 && d[2] >= 0x80) {
635                         /* we are starting a new block, so look for a PSC. */
636                         for (i = 3; i < len - 3; i++) {
637                                 if (d[i] == 0 && d[i+1] == 0 && d[i+2] >= 0x80) {
638                                         l = i;
639                                         break;
640                                 }
641                         }
642                 }
643                 if (l > out->mtu || l > len) { /* psc not found, split */
644                         l = MIN(len, out->mtu);
645                 }
646                 if (l < 1 || l > out->mtu) {
647                         ast_log(LOG_WARNING, "--- frame error l %d\n", l);
648                         break;
649                 }
650                 
651                 if (d[0] == 0 && d[1] == 0) { /* we start with a psc */
652                         h = 0;
653                 } else { /* no psc, create a header */
654                         h = 2;
655                 }
656
657                 f = create_video_frame(d, d+l, AST_FORMAT_H263_PLUS, h, cur);
658                 if (!f)
659                         break;
660
661                 data = f->data;
662                 if (h == 0) {   /* we start with a psc */
663                         data[0] |= 0x04;        // set P == 1, and we are done
664                 } else {        /* no psc, create a header */
665                         data[0] = data[1] = 0;  // P == 0
666                 }
667
668                 if (!cur)
669                         first = f;
670                 cur = f;
671         }
672
673         if (cur)
674                 cur->subclass |= 1; // RTP Marker
675
676         *tail = cur;    /* end of the list */
677         return first;
678 }
679
680 /*! \brief extract the bitstreem from the RTP payload.
681  * This is format dependent.
682  * For h263+, the format is defined in RFC 2429
683  * and basically has a fixed 2-byte header as follows:
684  * 5 bits       RR      reserved, shall be 0
685  * 1 bit        P       indicate a start/end condition,
686  *                      in which case the payload should be prepended
687  *                      by two zero-valued bytes.
688  * 1 bit        V       there is an additional VRC header after this header
689  * 6 bits       PLEN    length in bytes of extra picture header
690  * 3 bits       PEBIT   how many bits to be ignored in the last byte
691  *
692  * XXX the code below is not complete.
693  */
694 static int h263p_decap(struct fbuf_t *b, uint8_t *data, int len)
695 {
696         int PLEN;
697
698         if (len < 2) {
699                 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
700                 return 1;
701         }
702         PLEN = ( (data[0] & 1) << 5 ) | ( (data[1] & 0xf8) >> 3);
703
704         if (PLEN > 0) {
705                 data += PLEN;
706                 len -= PLEN;
707         }
708         if (data[0] & 4)        /* bit P */
709                 data[0] = data[1] = 0;
710         else {
711                 data += 2;
712                 len -= 2;
713         }
714         return fbuf_append(b, data, len, 0, 0); /* ignore trail bits */
715 }
716
717
718 /*
719  * generic encoder, used by the various protocols supported here.
720  * We assume that the buffer is empty at the beginning.
721  */
722 static int ffmpeg_encode(struct video_out_desc *v)
723 {
724         struct fbuf_t *b = &v->enc_out;
725         int i;
726
727         b->used = avcodec_encode_video(v->enc_ctx, b->data, b->size, v->frame);
728         i = avcodec_encode_video(v->enc_ctx, b->data + b->used, b->size - b->used, NULL); /* delayed frames ? */
729         if (i > 0) {
730                 ast_log(LOG_WARNING, "have %d more bytes\n", i);
731                 b->used += i;
732         }
733         return 0;
734 }
735
736 /*
737  * Generic decoder, which is used by h263p, h263 and h261 as it simply
738  * invokes ffmpeg's decoder.
739  * av_parser_parse should merge a randomly chopped up stream into
740  * proper frames. After that, if we have a valid frame, we decode it
741  * until the entire frame is processed.
742  */
743 static int ffmpeg_decode(struct video_in_desc *v, struct fbuf_t *b)
744 {
745         uint8_t *src = b->data;
746         int srclen = b->used;
747         int full_frame = 0;
748
749         if (srclen == 0)        /* no data */
750                 return 0;
751         if (0)
752                 check_h261(b);
753         // ast_log(LOG_WARNING, "rx size %d\n", srclen);
754         while (srclen) {
755                 uint8_t *data;
756                 int datalen, ret;
757                 int len = av_parser_parse(v->parser, v->dec_ctx, &data, &datalen, src, srclen, 0, 0);
758
759                 src += len;
760                 srclen -= len;
761                 /* The parser might return something it cannot decode, so it skips
762                  * the block returning no data
763                  */
764                 if (data == NULL || datalen == 0)
765                         continue;
766                 ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame, data, datalen);
767                 if (full_frame == 1)    /* full frame */
768                         break;
769                 if (ret < 0) {
770                         ast_log(LOG_NOTICE, "Error decoding\n");
771                         break;
772                 }
773         }
774         if (srclen != 0)        /* update b with leftover data */
775                 bcopy(src, b->data, srclen);
776         b->used = srclen;
777         b->ebit = 0;
778         return full_frame;
779 }
780
781 static struct video_codec_desc h263p_codec = {
782         .name = "h263p",
783         .format = AST_FORMAT_H263_PLUS,
784         .enc_init = h263p_enc_init,
785         .enc_encap = h263p_encap,
786         .enc_run = ffmpeg_encode,
787         .dec_init = NULL,
788         .dec_decap = h263p_decap,
789         .dec_run = ffmpeg_decode
790 };
791
792 /*--- Plain h263 support --------*/
793
794 static int h263_enc_init(struct video_out_desc *v)
795 {
796         /* XXX check whether these are supported */
797         v->enc_ctx->flags |= CODEC_FLAG_H263P_UMV;
798         v->enc_ctx->flags |= CODEC_FLAG_H263P_AIC;
799         v->enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
800         v->enc_ctx->flags |= CODEC_FLAG_AC_PRED;
801
802         v->enc_ctx->gop_size = v->fps*5;
803
804         return 0;
805 }
806
807 /*
808  * h263 encapsulation is specified in RFC2190. There are three modes
809  * defined (A, B, C), with 4, 8 and 12 bytes of header, respectively.
810  * The header is made as follows
811  *     0.....................|.......................|.............|....31
812  *      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
813  * FP = 0- mode A, (only one word of header)
814  * FP = 10 mode B, and also means this is an I or P frame
815  * FP = 11 mode C, and also means this is a PB frame.
816  * SBIT, EBIT nuber of bits to ignore at beginning (msbits) and end (lsbits)
817  * SRC  bits 6,7,8 from the h263 PTYPE field
818  * I = 0 intra-coded, 1 = inter-coded (bit 9 from PTYPE)
819  * U = 1 for Unrestricted Motion Vector (bit 10 from PTYPE)
820  * S = 1 for Syntax Based Arith coding (bit 11 from PTYPE)
821  * A = 1 for Advanced Prediction (bit 12 from PTYPE)
822  * R = reserved, must be 0
823  * DBQ = differential quantization, DBQUANT from h263, 0 unless we are using
824  *      PB frames
825  * TRB = temporal reference for bframes, also 0 unless this is a PB frame
826  * TR = temporal reference for P frames, also 0 unless PB frame.
827  *
828  * Mode B and mode C description omitted.
829  *
830  * An RTP frame can start with a PSC 0000 0000 0000 0000 1000 0
831  * or with a GBSC, which also has the first 17 bits as a PSC.
832  * Note - PSC are byte-aligned, GOB not necessarily. PSC start with
833  *      PSC:22 0000 0000 0000 0000 1000 00      picture start code
834  *      TR:8   .... ....                        temporal reference
835  *      PTYPE:13 or more                        ptype...
836  * If we don't fragment a GOB SBIT and EBIT = 0.
837  * reference, 8 bit) 
838  * 
839  * The assumption below is that we start with a PSC.
840  */
841 static struct ast_frame *h263_encap(struct video_out_desc *out,
842                 struct ast_frame **tail)
843 {
844         uint8_t *d = out->enc_out.data;
845         int start = 0, i, len = out->enc_out.used;
846         struct ast_frame *f, *cur = NULL, *first = NULL;
847         const int pheader_len = 4;      /* Use RFC-2190 Mode A */
848         uint8_t h263_hdr[12];   /* worst case, room for a type c header */
849         uint8_t *h = h263_hdr;  /* shorthand */
850
851 #define H263_MIN_LEN    6
852         if (len < H263_MIN_LEN) /* unreasonably small */
853                 return NULL;
854
855         bzero(h263_hdr, sizeof(h263_hdr));
856         /* Now set the header bytes. Only type A by now,
857          * and h[0] = h[2] = h[3] = 0 by default.
858          * PTYPE starts 30 bits in the picture, so the first useful
859          * bit for us is bit 36 i.e. within d[4] (0 is the msbit).
860          * SRC = d[4] & 0x1c goes into data[1] & 0xe0
861          * I   = d[4] & 0x02 goes into data[1] & 0x10
862          * U   = d[4] & 0x01 goes into data[1] & 0x08
863          * S   = d[5] & 0x80 goes into data[1] & 0x04
864          * A   = d[5] & 0x40 goes into data[1] & 0x02
865          * R   = 0           goes into data[1] & 0x01
866          * Optimizing it, we have
867          */
868         h[1] = ( (d[4] & 0x1f) << 3 ) | /* SRC, I, U */
869                 ( (d[5] & 0xc0) >> 5 );         /* S, A, R */
870
871         /* now look for the next PSC or GOB header. First try to hit
872          * a '0' byte then look around for the 0000 0000 0000 0000 1 pattern
873          * which is both in the PSC and the GBSC.
874          */
875         for (i = H263_MIN_LEN, start = 0; start < len; start = i, i += 3) {
876                 //ast_log(LOG_WARNING, "search at %d of %d/%d\n", i, start, len);
877                 for (; i < len ; i++) {
878                         uint8_t x, rpos, lpos;
879                         int rpos_i;     /* index corresponding to rpos */
880                         if (d[i] != 0)          /* cannot be in a GBSC */
881                                 continue;
882                         if (i > len - 1)
883                                 break;
884                         x = d[i+1];
885                         if (x == 0)     /* next is equally good */
886                                 continue;
887                         /* see if around us we can make 16 '0' bits for the GBSC.
888                          * Look for the first bit set on the right, and then
889                          * see if we have enough 0 on the left.
890                          * We are guaranteed to end before rpos == 0
891                          */
892                         for (rpos = 0x80, rpos_i = 8; rpos; rpos >>= 1, rpos_i--)
893                                 if (x & rpos)   /* found the '1' bit in GBSC */
894                                         break;
895                         x = d[i-1];             /* now look behind */
896                         for (lpos = rpos; lpos ; lpos >>= 1)
897                                 if (x & lpos)   /* too early, not a GBSC */
898                                         break;
899                         if (lpos)               /* as i said... */
900                                 continue;
901                         /* now we have a GBSC starting somewhere in d[i-1],
902                          * but it might be not byte-aligned
903                          */
904                         if (rpos == 0x80) {     /* lucky case */
905                                 i = i - 1;
906                         } else {        /* XXX to be completed */
907                                 ast_log(LOG_WARNING, "unaligned GBSC 0x%x %d\n",
908                                         rpos, rpos_i);
909                         }
910                         break;
911                 }
912                 /* This frame is up to offset i (not inclusive).
913                  * We do not split it yet even if larger than MTU.
914                  */
915                 f = create_video_frame(d + start, d+i, AST_FORMAT_H263,
916                                 pheader_len, cur);
917
918                 if (!f)
919                         break;
920                 bcopy(h, f->data, 4);   /* copy the h263 header */
921                 /* XXX to do: if not aligned, fix sbit and ebit,
922                  * then move i back by 1 for the next frame
923                  */
924                 if (!cur)
925                         first = f;
926                 cur = f;
927         }
928
929         if (cur)
930                 cur->subclass |= 1;     // RTP Marker
931
932         *tail = cur;
933         return first;
934 }
935
936 /* XXX We only drop the header here, but maybe we need more. */
937 static int h263_decap(struct fbuf_t *b, uint8_t *data, int len)
938 {
939         if (len < 4) {
940                 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
941                 return 1;       /* error */
942         }
943
944         if ( (data[0] & 0x80) == 0) {
945                 len -= 4;
946                 data += 4;
947         } else {
948                 ast_log(LOG_WARNING, "unsupported mode 0x%x\n",
949                         data[0]);
950                 return 1;
951         }
952         return fbuf_append(b, data, len, 0, 0); /* XXX no bit alignment support yet */
953 }
954
955 static struct video_codec_desc h263_codec = {
956         .name = "h263",
957         .format = AST_FORMAT_H263,
958         .enc_init = h263_enc_init,
959         .enc_encap = h263_encap,
960         .enc_run = ffmpeg_encode,
961         .dec_init = NULL,
962         .dec_decap = h263_decap,
963         .dec_run = ffmpeg_decode
964                                                 
965 };
966
967 /*---- h261 support -----*/
968 static int h261_enc_init(struct video_out_desc *v)
969 {
970         /* It is important to set rtp_payload_size = 0, otherwise
971          * ffmpeg in h261 mode will produce output that it cannot parse.
972          * Also try to send I frames more frequently than with other codecs.
973          */
974         v->enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */
975         v->enc_ctx->gop_size = v->fps*2;        /* be more responsive */
976
977         return 0;
978 }
979
980 /*
981  * The encapsulation of H261 is defined in RFC4587 which obsoletes RFC2032
982  * The bitstream is preceded by a 32-bit header word:
983  *  SBIT:3 EBIT:3 I:1 V:1 GOBN:4 MBAP:5 QUANT:5 HMVD:5 VMVD:5
984  * SBIT and EBIT are the bits to be ignored at beginning and end,
985  * I=1 if the stream has only INTRA frames - cannot change during the stream.
986  * V=0 if motion vector is not used. Cannot change.
987  * GOBN is the GOB number in effect at the start of packet, 0 if we
988  *      start with a GOB header
989  * QUANT is the quantizer in effect, 0 if we start with GOB header
990  * HMVD  reference horizontal motion vector. 10000 is forbidden
991  * VMVD  reference vertical motion vector, as above.
992  * Packetization should occur at GOB boundaries, and if not possible
993  * with MacroBlock fragmentation. However it is likely that blocks
994  * are not bit-aligned so we must take care of this.
995  */
996 static struct ast_frame *h261_encap(struct video_out_desc *out,
997                 struct ast_frame **tail)
998 {
999         uint8_t *d = out->enc_out.data;
1000         int start = 0, i, len = out->enc_out.used;
1001         struct ast_frame *f, *cur = NULL, *first = NULL;
1002         const int pheader_len = 4;
1003         uint8_t h261_hdr[4];
1004         uint8_t *h = h261_hdr;  /* shorthand */
1005         int sbit = 0, ebit = 0;
1006
1007 #define H261_MIN_LEN 10
1008         if (len < H261_MIN_LEN) /* unreasonably small */
1009                 return NULL;
1010
1011         bzero(h261_hdr, sizeof(h261_hdr));
1012
1013         /* Similar to the code in h263_encap, but the marker there is longer.
1014          * Start a few bytes within the bitstream to avoid hitting the marker
1015          * twice. Note we might access the buffer at len, but this is ok because
1016          * the caller has it oversized.
1017          */
1018         for (i = H261_MIN_LEN, start = 0; start < len - 1; start = i, i += 4) {
1019 #if 0   /* test - disable packetization */
1020                 i = len;        /* wrong... */
1021 #else
1022                 int found = 0, found_ebit = 0;  /* last GBSC position found */
1023                 for (; i < len ; i++) {
1024                         uint8_t x, rpos, lpos;
1025                         if (d[i] != 0)          /* cannot be in a GBSC */
1026                                 continue;
1027                         x = d[i+1];
1028                         if (x == 0)     /* next is equally good */
1029                                 continue;
1030                         /* See if around us we find 15 '0' bits for the GBSC.
1031                          * Look for the first bit set on the right, and then
1032                          * see if we have enough 0 on the left.
1033                          * We are guaranteed to end before rpos == 0
1034                          */
1035                         for (rpos = 0x80, ebit = 7; rpos; ebit--, rpos >>= 1)
1036                                 if (x & rpos)   /* found the '1' bit in GBSC */
1037                                         break;
1038                         x = d[i-1];             /* now look behind */
1039                         for (lpos = (rpos >> 1); lpos ; lpos >>= 1)
1040                                 if (x & lpos)   /* too early, not a GBSC */
1041                                         break;
1042                         if (lpos)               /* as i said... */
1043                                 continue;
1044                         /* now we have a GBSC starting somewhere in d[i-1],
1045                          * but it might be not byte-aligned. Just remember it.
1046                          */
1047                         if (i - start > out->mtu) /* too large, stop now */
1048                                 break;
1049                         found_ebit = ebit;
1050                         found = i;
1051                         i += 4; /* continue forward */
1052                 }
1053                 if (i >= len) { /* trim if we went too forward */
1054                         i = len;
1055                         ebit = 0;       /* hopefully... should ask the bitstream ? */
1056                 }
1057                 if (i - start > out->mtu && found) {
1058                         /* use the previous GBSC, hope is within the mtu */
1059                         i = found;
1060                         ebit = found_ebit;
1061                 }
1062 #endif /* test */
1063                 if (i - start < 4)      /* XXX too short ? */
1064                         continue;
1065                 /* This frame is up to offset i (not inclusive).
1066                  * We do not split it yet even if larger than MTU.
1067                  */
1068                 f = create_video_frame(d + start, d+i, AST_FORMAT_H261,
1069                                 pheader_len, cur);
1070
1071                 if (!f)
1072                         break;
1073                 /* recompute header with I=0, V=1 */
1074                 h[0] = ( (sbit & 7) << 5 ) | ( (ebit & 7) << 2 ) | 1;
1075                 bcopy(h, f->data, 4);   /* copy the h261 header */
1076                 if (ebit)       /* not aligned, restart from previous byte */
1077                         i--;
1078                 sbit = (8 - ebit) & 7;
1079                 ebit = 0;
1080                 if (!cur)
1081                         first = f;
1082                 cur = f;
1083         }
1084         if (cur)
1085                 cur->subclass |= 1;     // RTP Marker
1086
1087         *tail = cur;
1088         return first;
1089 }
1090
1091 /*
1092  * Pieces might be unaligned so we really need to put them together.
1093  */
1094 static int h261_decap(struct fbuf_t *b, uint8_t *data, int len)
1095 {
1096         int ebit, sbit;
1097
1098         if (len < 8) {
1099                 ast_log(LOG_WARNING, "invalid framesize %d\n", len);
1100                 return 1;
1101         }
1102         sbit = (data[0] >> 5) & 7;
1103         ebit = (data[0] >> 2) & 7;
1104         len -= 4;
1105         data += 4;
1106         return fbuf_append(b, data, len, sbit, ebit);
1107 }
1108
1109 static struct video_codec_desc h261_codec = {
1110         .name = "h261",
1111         .format = AST_FORMAT_H261,
1112         .enc_init = h261_enc_init,
1113         .enc_encap = h261_encap,
1114         .enc_run = ffmpeg_encode,
1115         .dec_init = NULL,
1116         .dec_decap = h261_decap,
1117         .dec_run = ffmpeg_decode
1118 };
1119
1120 /* mpeg4 support */
1121 static int mpeg4_enc_init(struct video_out_desc *v)
1122 {
1123 #if 0
1124         //v->enc_ctx->flags |= CODEC_FLAG_LOW_DELAY; /*don't use b frames ?*/
1125         v->enc_ctx->flags |= CODEC_FLAG_AC_PRED;
1126         v->enc_ctx->flags |= CODEC_FLAG_H263P_UMV;
1127         v->enc_ctx->flags |= CODEC_FLAG_QPEL;
1128         v->enc_ctx->flags |= CODEC_FLAG_4MV;
1129         v->enc_ctx->flags |= CODEC_FLAG_GMC;
1130         v->enc_ctx->flags |= CODEC_FLAG_LOOP_FILTER;
1131         v->enc_ctx->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
1132 #endif
1133         v->enc_ctx->gop_size = v->fps*5;
1134         v->enc_ctx->rtp_payload_size = 0; /* important - ffmpeg fails otherwise */
1135         return 0;
1136 }
1137
1138 /* simplistic encapsulation - just split frames in mtu-size units */
1139 static struct ast_frame *mpeg4_encap(struct  video_out_desc *out,
1140         struct ast_frame **tail)
1141 {
1142         struct ast_frame *f, *cur = NULL, *first = NULL;
1143         uint8_t *d = out->enc_out.data;
1144         uint8_t *end = d+out->enc_out.used;
1145         int len;
1146
1147         for (;d < end; d += len, cur = f) {
1148                 len = MIN(out->mtu, end-d);
1149                 f = create_video_frame(d, d+len, AST_FORMAT_MP4_VIDEO, 0, cur);
1150                 if (!f)
1151                         break;
1152                 if (!first)
1153                         first = f;
1154         }
1155         if (cur)
1156                 cur->subclass |= 1;
1157         *tail = cur;
1158         return first;
1159 }
1160
1161 static int mpeg4_decap(struct fbuf_t *b, uint8_t *data, int len)
1162 {
1163         return fbuf_append(b, data, len, 0, 0);
1164 }
1165
1166 static int mpeg4_decode(struct video_in_desc *v, struct fbuf_t *b)
1167 {
1168         int full_frame = 0, datalen = b->used;
1169         int ret = avcodec_decode_video(v->dec_ctx, v->d_frame, &full_frame,
1170                 b->data, datalen);
1171         if (ret < 0) {
1172                 ast_log(LOG_NOTICE, "Error decoding\n");
1173                 ret = datalen; /* assume we used everything. */
1174         }
1175         datalen -= ret;
1176         if (datalen > 0)        /* update b with leftover bytes */
1177                 bcopy(b->data + ret, b->data, datalen);
1178         b->used = datalen;
1179         b->ebit = 0;
1180         return full_frame;
1181 }
1182
1183 static struct video_codec_desc mpeg4_codec = {
1184         .name = "mpeg4",
1185         .format = AST_FORMAT_MP4_VIDEO,
1186         .enc_init = mpeg4_enc_init,
1187         .enc_encap = mpeg4_encap,
1188         .enc_run = ffmpeg_encode,
1189         .dec_init = NULL,
1190         .dec_decap = mpeg4_decap,
1191         .dec_run = mpeg4_decode
1192 };
1193
1194 static int h264_enc_init(struct video_out_desc *v)
1195 {
1196         v->enc_ctx->flags |= CODEC_FLAG_TRUNCATED;
1197         //v->enc_ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
1198         //v->enc_ctx->flags2 |= CODEC_FLAG2_FASTPSKIP;
1199         /* TODO: Maybe we need to add some other flags */
1200         v->enc_ctx->gop_size = v->fps*5; // emit I frame every 5 seconds
1201         v->enc_ctx->rtp_mode = 0;
1202         v->enc_ctx->rtp_payload_size = 0;
1203         v->enc_ctx->bit_rate_tolerance = v->enc_ctx->bit_rate;
1204         return 0;
1205 }
1206
1207 static int h264_dec_init(struct video_in_desc *v)
1208 {
1209         v->dec_ctx->flags |= CODEC_FLAG_TRUNCATED;
1210
1211         return 0;
1212 }
1213
1214 /*
1215  * The structure of a generic H.264 stream is:
1216  * - 0..n 0-byte(s), unused, optional. one zero-byte is always present
1217  *   in the first NAL before the start code prefix.
1218  * - start code prefix (3 bytes): 0x000001
1219  *   (the first bytestream has a 
1220  *   like these 0x00000001!)
1221  * - NAL header byte ( F[1] | NRI[2] | Type[5] ) where type != 0
1222  * - byte-stream
1223  * - 0..n 0-byte(s) (padding, unused).
1224  * Segmentation in RTP only needs to be done on start code prefixes.
1225  * If fragments are too long... we don't support it yet.
1226  * - encapsulate (or fragment) the byte-stream (with NAL header included)
1227  */
1228 static struct ast_frame *h264_encap(struct video_out_desc *out,
1229         struct ast_frame **tail)
1230 {
1231         struct ast_frame *f = NULL, *cur = NULL, *first = NULL;
1232         uint8_t *d, *start = out->enc_out.data;
1233         uint8_t *end = start + out->enc_out.used;
1234
1235         /* Search the first start code prefix - ITU-T H.264 sec. B.2,
1236          * and move start right after that, on the NAL header byte.
1237          */
1238 #define HAVE_NAL(x) (x[-4] == 0 && x[-3] == 0 && x[-2] == 0 && x[-1] == 1)
1239         for (start += 4; start < end; start++) {
1240                 int ty = start[0] & 0x1f;
1241                 if (HAVE_NAL(start) && ty != 0 && ty != 31)
1242                         break;
1243         }
1244         /* if not found, or too short, we just skip the next loop and are done. */
1245
1246         /* Here follows the main loop to create frames. Search subsequent start
1247          * codes, and then possibly fragment the unit into smaller fragments.
1248          */
1249    for (;start < end - 4; start = d) {
1250         int size;               /* size of current block */
1251         uint8_t hdr[2];         /* add-on header when fragmenting */
1252         int ty = 0;
1253
1254         /* now search next nal */
1255         for (d = start + 4; d < end; d++) {
1256                 ty = d[0] & 0x1f;
1257                 if (HAVE_NAL(d))
1258                         break;  /* found NAL */
1259         }
1260         /* have a block to send. d past the start code unless we overflow */
1261         if (d >= end) { /* NAL not found */
1262                 d = end + 4;
1263         } else if (ty == 0 || ty == 31) { /* found but invalid type, skip */
1264                 ast_log(LOG_WARNING, "skip invalid nal type %d at %d of %d\n",
1265                         ty, d - out->enc_out.data, out->enc_out.used);
1266                 continue;
1267         }
1268
1269         size = d - start - 4;   /* don't count the end */
1270
1271         if (size < out->mtu) {  // test - don't fragment
1272                 // Single NAL Unit
1273                 f = create_video_frame(start, d - 4, AST_FORMAT_H264, 0, cur);
1274                 if (!f)
1275                         break;
1276                 if (!first)
1277                         first = f;
1278
1279                 cur = f;
1280                 continue;
1281         }
1282
1283         // Fragmented Unit (Mode A: no DON, very weak)
1284         hdr[0] = (*start & 0xe0) | 28;  /* mark as a fragmentation unit */
1285         hdr[1] = (*start++ & 0x1f) | 0x80 ;     /* keep type and set START bit */
1286         size--;         /* skip the NAL header */
1287         while (size) {
1288                 uint8_t *data;
1289                 int frag_size = MIN(size, out->mtu);
1290
1291                 f = create_video_frame(start, start+frag_size, AST_FORMAT_H264, 2, cur);
1292                 if (!f)
1293                         break;
1294                 size -= frag_size;      /* skip this data block */
1295                 start += frag_size;
1296
1297                 data = f->data;
1298                 data[0] = hdr[0];
1299                 data[1] = hdr[1] | (size == 0 ? 0x40 : 0);      /* end bit if we are done */
1300                 hdr[1] &= ~0x80;        /* clear start bit for subsequent frames */
1301                 if (!first)
1302                         first = f;
1303                 cur = f;
1304         }
1305     }
1306
1307         if (cur)
1308                 cur->subclass |= 1;     // RTP Marker
1309
1310         *tail = cur;
1311
1312         return first;
1313 }
1314
1315 static int h264_decap(struct fbuf_t *b, uint8_t *data, int len)
1316 {
1317         /* Start Code Prefix (Annex B in specification) */
1318         uint8_t scp[] = { 0x00, 0x00, 0x00, 0x01 };
1319         int retval = 0;
1320         int type, ofs = 0;
1321
1322         if (len < 2) {
1323                 ast_log(LOG_WARNING, "--- invalid len %d\n", len);
1324                 return 1;
1325         }
1326         /* first of all, check if the packet has F == 0 */
1327         if (data[0] & 0x80) {
1328                 ast_log(LOG_WARNING, "--- forbidden packet; nal: %02x\n",
1329                         data[0]);
1330                 return 1;
1331         }
1332
1333         type = data[0] & 0x1f;
1334         switch (type) {
1335         case 0:
1336         case 31:
1337                 ast_log(LOG_WARNING, "--- invalid type: %d\n", type);
1338                 return 1;
1339         case 24:
1340         case 25:
1341         case 26:
1342         case 27:
1343         case 29:
1344                 ast_log(LOG_WARNING, "--- encapsulation not supported : %d\n", type);
1345                 return 1;
1346         case 28:        /* FU-A Unit */
1347                 if (data[1] & 0x80) { // S == 1, import F and NRI from next
1348                         data[1] &= 0x1f;        /* preserve type */
1349                         data[1] |= (data[0] & 0xe0);    /* import F & NRI */
1350                         retval = fbuf_append(b, scp, sizeof(scp), 0, 0);
1351                         ofs = 1;
1352                 } else {
1353                         ofs = 2;
1354                 }
1355                 break;
1356         default:        /* From 1 to 23 (Single NAL Unit) */
1357                 retval = fbuf_append(b, scp, sizeof(scp), 0, 0);
1358         }
1359         if (!retval)
1360                 retval = fbuf_append(b, data + ofs, len - ofs, 0, 0);
1361         if (retval)
1362                 ast_log(LOG_WARNING, "result %d\n", retval);
1363         return retval;
1364 }
1365
1366 static struct video_codec_desc h264_codec = {
1367         .name = "h264",
1368         .format = AST_FORMAT_H264,
1369         .enc_init = h264_enc_init,
1370         .enc_encap = h264_encap,
1371         .enc_run = ffmpeg_encode,
1372         .dec_init = h264_dec_init,
1373         .dec_decap = h264_decap,
1374         .dec_run = ffmpeg_decode
1375 };
1376
1377 /*------ end codec specific code -----*/
1378
1379
1380 /* Video4Linux stuff is only used in video_open() */
1381 #ifdef HAVE_VIDEODEV_H
1382 #include <linux/videodev.h>
1383 #endif
1384
1385 /*!
1386  * Open the local video source and allocate a buffer
1387  * for storing the image. Return 0 on success, -1 on error
1388  */
1389 static int video_open(struct video_out_desc *v)
1390 {
1391         struct fbuf_t *b = &v->loc_src;
1392         if (b->data)    /* buffer allocated means device already open */
1393                 return v->fd;
1394         v->fd = -1;
1395         /*
1396          * if the device is "X11", then open the x11 grabber
1397          */
1398     if (!strcasecmp(v->videodevice, "X11")) {
1399         XImage *im;
1400         int screen_num;
1401
1402         /* init the connection with the X server */
1403         v->dpy = XOpenDisplay(NULL);
1404         if (v->dpy == NULL) {
1405                 ast_log(LOG_WARNING, "error opening display\n");
1406                 goto error;
1407         }
1408
1409         /* find width and height of the screen */
1410         screen_num = DefaultScreen(v->dpy);
1411         v->screen_width = DisplayWidth(v->dpy, screen_num);
1412         v->screen_height = DisplayHeight(v->dpy, screen_num);
1413
1414         v->image = im = XGetImage(v->dpy,
1415                 RootWindow(v->dpy, DefaultScreen(v->dpy)),
1416                 b->x, b->y, b->w, b->h, AllPlanes, ZPixmap);
1417         if (v->image == NULL) {
1418                 ast_log(LOG_WARNING, "error creating Ximage\n");
1419                 goto error;
1420         }
1421         switch (im->bits_per_pixel) {
1422         case 32:
1423                 b->pix_fmt = PIX_FMT_RGBA32;
1424                 break;
1425         case 16:
1426                 b->pix_fmt = (im->green_mask == 0x7e0) ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
1427                 break;
1428         }
1429
1430         ast_log(LOG_NOTICE, "image: data %p %d bpp fmt %d, mask 0x%lx 0x%lx 0x%lx\n",
1431                 im->data,
1432                 im->bits_per_pixel,
1433                 b->pix_fmt,
1434                 im->red_mask, im->green_mask, im->blue_mask);
1435
1436         /* set the pointer but not the size as this is not malloc'ed */
1437         b->data = (uint8_t *)im->data;
1438         v->fd = -2;
1439     }
1440 #ifdef HAVE_VIDEODEV_H
1441     else {
1442         /* V4L specific */
1443         struct video_window vw = { 0 }; /* camera attributes */
1444         struct video_picture vp;
1445         int i;
1446         const char *dev = v->videodevice;
1447
1448         v->fd = open(dev, O_RDONLY | O_NONBLOCK);
1449         if (v->fd < 0) {
1450                 ast_log(LOG_WARNING, "error opening camera %s\n", v->videodevice);
1451                 return v->fd;
1452         }
1453
1454         i = fcntl(v->fd, F_GETFL);
1455         if (-1 == fcntl(v->fd, F_SETFL, i | O_NONBLOCK)) {
1456                 /* non fatal, just emit a warning */
1457                 ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n",
1458                         dev, strerror(errno));
1459         }
1460         /* set format for the camera.
1461          * In principle we could retry with a different format if the
1462          * one we are asking for is not supported.
1463          */
1464         vw.width = v->loc_src.w;
1465         vw.height = v->loc_src.h;
1466         vw.flags = v->fps << 16;
1467         if (ioctl(v->fd, VIDIOCSWIN, &vw) == -1) {
1468                 ast_log(LOG_WARNING, "error setting format for %s [%s]\n",
1469                         dev, strerror(errno));
1470                 goto error;
1471         }
1472         if (ioctl(v->fd, VIDIOCGPICT, &vp) == -1) {
1473                 ast_log(LOG_WARNING, "error reading picture info\n");
1474                 goto error;
1475         }
1476         ast_log(LOG_WARNING,
1477                 "contrast %d bright %d colour %d hue %d white %d palette %d\n",
1478                 vp.contrast, vp.brightness,
1479                 vp.colour, vp.hue,
1480                 vp.whiteness, vp.palette);
1481         /* set the video format. Here again, we don't necessary have to
1482          * fail if the required format is not supported, but try to use
1483          * what the camera gives us.
1484          */
1485         b->pix_fmt = vp.palette;
1486         vp.palette = VIDEO_PALETTE_YUV420P;
1487         if (ioctl(v->fd, VIDIOCSPICT, &vp) == -1) {
1488                 ast_log(LOG_WARNING, "error setting palette, using %d\n",
1489                         b->pix_fmt);
1490         } else
1491                 b->pix_fmt = vp.palette;
1492         /* allocate the source buffer.
1493          * XXX, the code here only handles yuv411, for other formats
1494          * we need to look at pix_fmt and set size accordingly
1495          */
1496         b->size = (b->w * b->h * 3)/2;  /* yuv411 */
1497         ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n",
1498                 dev, b->w, b->h, b->size);
1499         v->loc_src.data = ast_calloc(1, b->size);
1500         if (!b->data) {
1501                 ast_log(LOG_WARNING, "error allocating buffer %d bytes\n",
1502                         b->size);
1503                 goto error;
1504         }
1505         ast_log(LOG_WARNING, "success opening camera\n");
1506     }
1507 #endif /* HAVE_VIDEODEV_H */
1508
1509         if (v->image == NULL && v->fd < 0)
1510                 goto error;
1511         b->used = 0;
1512         return 0;
1513
1514 error:
1515         ast_log(LOG_WARNING, "fd %d dpy %p img %p data %p\n",
1516                 v->fd, v->dpy, v->image, v->loc_src.data);
1517         /* XXX maybe XDestroy (v->image) ? */
1518         if (v->dpy)
1519                 XCloseDisplay(v->dpy);
1520         v->dpy = NULL;
1521         if (v->fd >= 0)
1522                 close(v->fd);
1523         v->fd = -1;
1524         fbuf_free(&v->loc_src);
1525         return -1;
1526 }
1527
1528 /*! \brief complete a buffer from the local video source.
1529  * Called by get_video_frames(), in turn called by the video thread.
1530  */
1531 static int video_read(struct video_out_desc *v)
1532 {
1533         struct timeval now = ast_tvnow();
1534         struct fbuf_t *b = &v->loc_src;
1535
1536         if (b->data == NULL)    /* not initialized */
1537                 return 0;
1538
1539         /* check if it is time to read */
1540         if (ast_tvzero(v->last_frame))
1541                 v->last_frame = now;
1542         if (ast_tvdiff_ms(now, v->last_frame) < 1000/v->fps)
1543                 return 0;       /* too early */
1544         v->last_frame = now; /* XXX actually, should correct for drift */
1545
1546 #ifdef HAVE_X11
1547         if (v->image) {
1548                 /* read frame from X11 */
1549                 AVPicture p;
1550                 XGetSubImage(v->dpy,
1551                     RootWindow(v->dpy, DefaultScreen(v->dpy)),
1552                         b->x, b->y, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);
1553
1554                 b->data = (uint8_t *)v->image->data;
1555                 fill_pict(b, &p);
1556                 return p.linesize[0] * b->h;
1557         }
1558 #endif
1559         if (v->fd < 0)                  /* no other source */
1560                 return 0;
1561         for (;;) {
1562                 int r, l = v->loc_src.size - v->loc_src.used;
1563                 r = read(v->fd, v->loc_src.data + v->loc_src.used, l);
1564                 // ast_log(LOG_WARNING, "read %d of %d bytes from webcam\n", r, l);
1565                 if (r < 0)      /* read error */
1566                         return 0;
1567                 if (r == 0)     /* no data */
1568                         return 0;
1569                 v->loc_src.used += r;
1570                 if (r == l) {
1571                         v->loc_src.used = 0; /* prepare for next frame */
1572                         return v->loc_src.size;
1573                 }
1574         }
1575 }
1576
1577 /* Helper function to process incoming video.
1578  * For each incoming video call invoke ffmpeg_init() to intialize
1579  * the decoding structure then incoming video frames are processed
1580  * by write_video() which in turn calls pre_process_data(), to extract
1581  * the bitstream; accumulates data into a buffer within video_desc. When
1582  * a frame is complete (determined by the marker bit in the RTP header)
1583  * call decode_video() to decoding and if it successful call show_frame()
1584  * to display the frame.
1585  */
1586
1587 /*
1588  * Table of translation between asterisk and ffmpeg formats.
1589  * We need also a field for read and write (encoding and decoding), because
1590  * e.g. H263+ uses different codec IDs in ffmpeg when encoding or decoding.
1591  */
1592 struct _cm {    /* map ffmpeg codec types to asterisk formats */
1593         uint32_t        ast_format;     /* 0 is a terminator */
1594         enum CodecID    codec;
1595         enum { CM_RD = 1, CM_WR = 2, CM_RDWR = 3 } rw;  /* read or write or both ? */
1596         struct video_codec_desc *codec_desc;
1597 };
1598
1599 static struct _cm video_formats[] = {
1600         { AST_FORMAT_H263_PLUS, CODEC_ID_H263,  CM_RD }, /* incoming H263P ? */
1601         { AST_FORMAT_H263_PLUS, CODEC_ID_H263P, CM_WR },
1602         { AST_FORMAT_H263,      CODEC_ID_H263,  CM_RD },
1603         { AST_FORMAT_H263,      CODEC_ID_H263,  CM_WR },
1604         { AST_FORMAT_H261,      CODEC_ID_H261,  CM_RDWR },
1605         { AST_FORMAT_H264,      CODEC_ID_H264,  CM_RDWR },
1606         { AST_FORMAT_MP4_VIDEO, CODEC_ID_MPEG4, CM_RDWR },
1607         { 0,                    0, 0 },
1608 };
1609
1610
1611 /*! \brief map an asterisk format into an ffmpeg one */
1612 static enum CodecID map_video_format(uint32_t ast_format, int rw)
1613 {
1614         struct _cm *i;
1615
1616         for (i = video_formats; i->ast_format != 0; i++)
1617                 if (ast_format & i->ast_format && rw & i->rw && rw & i->rw)
1618                         return i->codec;
1619         return CODEC_ID_NONE;
1620 }
1621
1622 /* pointers to supported codecs. We assume the first one to be non null. */
1623 static struct video_codec_desc *supported_codecs[] = {
1624         &h263p_codec,
1625         &h264_codec,
1626         &h263_codec,
1627         &h261_codec,
1628         &mpeg4_codec,
1629         NULL
1630 };
1631
1632 /*
1633  * Map the AST_FORMAT to the library. If not recognised, fail.
1634  * This is useful in the input path where we get frames.
1635  */
1636 static struct video_codec_desc *map_video_codec(int fmt)
1637 {
1638         int i;
1639
1640         for (i = 0; supported_codecs[i]; i++)
1641                 if (fmt == supported_codecs[i]->format) {
1642                         ast_log(LOG_WARNING, "using %s for format 0x%x\n",
1643                                 supported_codecs[i]->name, fmt);
1644                         return supported_codecs[i];
1645                 }
1646         return NULL;
1647 }
1648 ;
1649 /*
1650  * Map the codec name to the library. If not recognised, use a default.
1651  * This is useful in the output path where we decide by name, presumably.
1652  */
1653 static struct video_codec_desc *map_config_video_format(char *name)
1654 {
1655         int i;
1656
1657         for (i = 0; supported_codecs[i]; i++)
1658                 if (!strcasecmp(name, supported_codecs[i]->name))
1659                         break;
1660         if (supported_codecs[i] == NULL) {
1661                 ast_log(LOG_WARNING, "Cannot find codec for '%s'\n", name);
1662                 i = 0;
1663                 strcpy(name, supported_codecs[i]->name);
1664         }
1665         ast_log(LOG_WARNING, "Using codec '%s'\n", name);
1666         return supported_codecs[i];
1667 }
1668
1669 /*! \brief uninitialize the descriptor for remote video stream */
1670 static int video_in_uninit(struct video_in_desc *v)
1671 {
1672         int i;
1673
1674         if (v->parser) {
1675                 av_parser_close(v->parser);
1676                 v->parser = NULL;
1677         }
1678         if (v->dec_ctx) {
1679                 avcodec_close(v->dec_ctx);
1680                 av_free(v->dec_ctx);
1681                 v->dec_ctx = NULL;
1682         }
1683         if (v->d_frame) {
1684                 av_free(v->d_frame);
1685                 v->d_frame = NULL;
1686         }
1687         v->codec = NULL;        /* only a reference */
1688         v->dec = NULL;          /* forget the decoder */
1689         v->discard = 1;         /* start in discard mode */
1690         for (i = 0; i < N_DEC_IN; i++)
1691                 fbuf_free(&v->dec_in[i]);
1692         fbuf_free(&v->dec_out);
1693         fbuf_free(&v->rem_dpy);
1694         return -1;      /* error, in case someone cares */
1695 }
1696
1697 /*
1698  * initialize ffmpeg resources used for decoding frames from the network.
1699  */
1700 static int video_in_init(struct video_in_desc *v, uint32_t format)
1701 {
1702         enum CodecID codec;
1703
1704         /* XXX should check that these are already set */
1705         v->codec = NULL;
1706         v->dec_ctx = NULL;
1707         v->d_frame = NULL;
1708         v->parser = NULL;
1709         v->discard = 1;
1710
1711         codec = map_video_format(format, CM_RD);
1712
1713         v->codec = avcodec_find_decoder(codec);
1714         if (!v->codec) {
1715                 ast_log(LOG_WARNING, "Unable to find the decoder for format %d\n", codec);
1716                 return video_in_uninit(v);
1717         }
1718         /*
1719         * Initialize the codec context.
1720         */
1721         v->dec_ctx = avcodec_alloc_context();
1722         if (avcodec_open(v->dec_ctx, v->codec) < 0) {
1723                 ast_log(LOG_WARNING, "Cannot open the codec context\n");
1724                 av_free(v->dec_ctx);
1725                 v->dec_ctx = NULL;
1726                 return video_in_uninit(v);
1727         }
1728
1729         v->parser = av_parser_init(codec);
1730         if (!v->parser) {
1731                 ast_log(LOG_WARNING, "Cannot initialize the decoder parser\n");
1732                 return video_in_uninit(v);
1733         }
1734
1735         v->d_frame = avcodec_alloc_frame();
1736         if (!v->d_frame) {
1737                 ast_log(LOG_WARNING, "Cannot allocate decoding video frame\n");
1738                 return video_in_uninit(v);
1739         }
1740         return 0;       /* ok */
1741 }
1742
1743 /*! \brief uninitialize the descriptor for local video stream */
1744 static int video_out_uninit(struct video_out_desc *v)
1745 {
1746         if (v->enc_ctx) {
1747                 avcodec_close(v->enc_ctx);
1748                 av_free(v->enc_ctx);
1749                 v->enc_ctx = NULL;
1750         }
1751         if (v->frame) {
1752                 av_free(v->frame);
1753                 v->frame = NULL;
1754         }
1755         v->codec = NULL;        /* only a reference */
1756         
1757         fbuf_free(&v->loc_src);
1758         fbuf_free(&v->enc_in);
1759         fbuf_free(&v->enc_out);
1760         fbuf_free(&v->loc_dpy);
1761         if (v->image) { /* X11 grabber */
1762                 XCloseDisplay(v->dpy);
1763                 v->dpy = NULL;
1764                 v->image = NULL;
1765         }
1766         if (v->fd >= 0) {
1767                 close(v->fd);
1768                 v->fd = -1;
1769         }
1770         return -1;
1771 }
1772
1773 /*
1774  * Initialize the encoder for the local source:
1775  * - AVCodecContext, AVCodec, AVFrame are used by ffmpeg for encoding;
1776  * - encbuf is used to store the encoded frame (to be sent)
1777  * - mtu is used to determine the max size of video fragment
1778  * NOTE: we enter here with the video source already open.
1779  */
1780 static int video_out_init(struct video_desc *env)
1781 {
1782         int codec;
1783         int size;
1784         struct fbuf_t *enc_in;
1785         struct video_out_desc *v = &env->out;
1786
1787         v->enc_ctx              = NULL;
1788         v->codec                = NULL;
1789         v->frame                = NULL;
1790         v->enc_out.data         = NULL;
1791
1792         if (v->loc_src.data == NULL) {
1793                 ast_log(LOG_WARNING, "No local source active\n");
1794                 return video_out_uninit(v);
1795         }
1796         codec = map_video_format(v->enc->format, CM_WR);
1797         v->codec = avcodec_find_encoder(codec);
1798         if (!v->codec) {
1799                 ast_log(LOG_WARNING, "Cannot find the encoder for format %d\n",
1800                         codec);
1801                 return video_out_uninit(v);
1802         }
1803
1804         v->mtu = 1400;  /* set it early so the encoder can use it */
1805
1806         /* allocate the input buffer for encoding.
1807          * ffmpeg only supports PIX_FMT_YUV420P for the encoding.
1808          */
1809         enc_in = &v->enc_in;
1810         enc_in->pix_fmt = PIX_FMT_YUV420P;
1811         enc_in->size = (enc_in->w * enc_in->h * 3)/2;
1812         enc_in->data = ast_calloc(1, enc_in->size);
1813         if (!enc_in->data) {
1814                 ast_log(LOG_WARNING, "Cannot allocate encoder input buffer\n");
1815                 return video_out_uninit(v);
1816         }
1817         v->frame = avcodec_alloc_frame();
1818         if (!v->frame) {
1819                 ast_log(LOG_WARNING, "Unable to allocate the encoding video frame\n");
1820                 return video_out_uninit(v);
1821         }
1822
1823         /* parameters for PIX_FMT_YUV420P */
1824         size = enc_in->w * enc_in->h;
1825         v->frame->data[0] = enc_in->data;
1826         v->frame->data[1] = v->frame->data[0] + size;
1827         v->frame->data[2] = v->frame->data[1] + size/4;
1828         v->frame->linesize[0] = enc_in->w;
1829         v->frame->linesize[1] = enc_in->w/2;
1830         v->frame->linesize[2] = enc_in->w/2;
1831
1832         /* now setup the parameters for the encoder */
1833         v->enc_ctx = avcodec_alloc_context();
1834         v->enc_ctx->pix_fmt = enc_in->pix_fmt;
1835         v->enc_ctx->width = enc_in->w;
1836         v->enc_ctx->height = enc_in->h;
1837         /* XXX rtp_callback ?
1838          * rtp_mode so ffmpeg inserts as many start codes as possible.
1839          */
1840         v->enc_ctx->rtp_mode = 1;
1841         v->enc_ctx->rtp_payload_size = v->mtu / 2; // mtu/2
1842         v->enc_ctx->bit_rate = v->bitrate;
1843         v->enc_ctx->bit_rate_tolerance = v->enc_ctx->bit_rate/2;
1844         v->enc_ctx->qmin = v->qmin;     /* should be configured */
1845         v->enc_ctx->time_base = (AVRational){1, v->fps};
1846
1847         v->enc->enc_init(v);
1848  
1849         if (avcodec_open(v->enc_ctx, v->codec) < 0) {
1850                 ast_log(LOG_WARNING, "Unable to initialize the encoder %d\n",
1851                         codec);
1852                 av_free(v->enc_ctx);
1853                 v->enc_ctx = NULL;
1854                 return video_out_uninit(v);
1855         }
1856
1857         /*
1858          * Allocate enough for the encoded bitstream. As we are compressing,
1859          * we hope that the output is never larger than the input size.
1860          */
1861         v->enc_out.data = ast_calloc(1, enc_in->size);
1862         v->enc_out.size = enc_in->size;
1863         v->enc_out.used = 0;
1864
1865         return 0;
1866 }
1867
1868 static void cleanup_sdl(struct video_desc *env)  
1869 {
1870         int i;
1871
1872 #ifdef HAVE_SDL_TTF
1873         /* unload font file */ 
1874         if (env->gui.font) {
1875                 TTF_CloseFont(env->gui.font);
1876                 env->gui.font = NULL; 
1877         }
1878
1879         /* uninitialize SDL_ttf library */
1880         if ( TTF_WasInit() )
1881                 TTF_Quit();
1882 #endif
1883
1884         /* uninitialize the SDL environment */
1885         for (i = 0; i < WIN_MAX; i++) {
1886                 if (env->win[i].bmp)
1887                         SDL_FreeYUVOverlay(env->win[i].bmp);
1888         }
1889         if (env->gui.keypad)
1890                 SDL_FreeSurface(env->gui.keypad);
1891         env->gui.keypad = NULL;
1892         SDL_Quit();
1893         env->screen = NULL; /* XXX check reference */
1894         bzero(env->win, sizeof(env->win));
1895         if (env->sdl_ok)
1896                 ast_mutex_destroy(&(env->in.dec_in_lock));
1897 }
1898
1899 /*! \brief uninitialize the entire environment.
1900  * In practice, signal the thread and give it a bit of time to
1901  * complete, giving up if it gets stuck. Because uninit
1902  * is called from hangup with the channel locked, and the thread
1903  * uses the chan lock, we need to unlock here. This is unsafe,
1904  * and we should really use refcounts for the channels.
1905  */
1906 void console_video_uninit(struct video_desc *env)
1907 {
1908         int i, t = 100; /* initial wait is shorter, than make it longer */
1909         env->shutdown = 1;
1910         for (i=0; env->shutdown && i < 10; i++) {
1911                 ast_channel_unlock(env->owner);
1912                 usleep(t);
1913                 t = 1000000;
1914                 ast_channel_lock(env->owner);
1915         }
1916         env->owner = NULL;
1917 }
1918
1919 /*! fill an AVPicture from our fbuf info, as it is required by
1920  * the image conversion routines in ffmpeg.
1921  * XXX This depends on the format.
1922  */
1923 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p)
1924 {
1925         /* provide defaults for commonly used formats */
1926         int l4 = b->w * b->h/4; /* size of U or V frame */
1927         int len = b->w;         /* Y linesize, bytes */
1928         int luv = b->w/2;       /* U/V linesize, bytes */
1929
1930         bzero(p, sizeof(*p));
1931         switch (b->pix_fmt) {
1932         case PIX_FMT_RGB555:
1933         case PIX_FMT_RGB565:
1934                 len *= 2;
1935                 luv = 0;
1936                 break;
1937         case PIX_FMT_RGBA32:
1938                 len *= 4;
1939                 luv = 0;
1940                 break;
1941         case PIX_FMT_YUYV422:   /* Packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr */
1942                 len *= 2;       /* all data in first plane, probably */
1943                 luv = 0;
1944                 break;
1945         }
1946         p->data[0] = b->data;
1947         p->linesize[0] = len;
1948         /* these are only valid for component images */
1949         p->data[1] = luv ? b->data + 4*l4 : b->data+len;
1950         p->data[2] = luv ? b->data + 5*l4 : b->data+len;
1951         p->linesize[1] = luv;
1952         p->linesize[2] = luv;
1953         return p;
1954 }
1955
1956 /*! convert/scale between an input and an output format.
1957  * Old version of ffmpeg only have img_convert, which does not rescale.
1958  * New versions use sws_scale which does both.
1959  */
1960 static void my_scale(struct fbuf_t *in, AVPicture *p_in,
1961         struct fbuf_t *out, AVPicture *p_out)
1962 {
1963         AVPicture my_p_in, my_p_out;
1964
1965         if (p_in == NULL)
1966                 p_in = fill_pict(in, &my_p_in);
1967         if (p_out == NULL)
1968                 p_out = fill_pict(out, &my_p_out);
1969
1970 #ifdef OLD_FFMPEG
1971         /* XXX img_convert is deprecated, and does not do rescaling */
1972         img_convert(p_out, out->pix_fmt,
1973                 p_in, in->pix_fmt, in->w, in->h);
1974 #else /* XXX replacement */
1975     {
1976         struct SwsContext *convert_ctx;
1977
1978         convert_ctx = sws_getContext(in->w, in->h, in->pix_fmt,
1979                 out->w, out->h, out->pix_fmt,
1980                 SWS_BICUBIC, NULL, NULL, NULL);
1981         if (convert_ctx == NULL) {
1982                 ast_log(LOG_ERROR, "FFMPEG::convert_cmodel : swscale context initialization failed");
1983                 return;
1984         }
1985         if (0)
1986                 ast_log(LOG_WARNING, "in %d %dx%d out %d %dx%d\n",
1987                         in->pix_fmt, in->w, in->h, out->pix_fmt, out->w, out->h);
1988         sws_scale(convert_ctx,
1989                 p_in->data, p_in->linesize,
1990                 in->w, in->h, /* src slice */
1991                 p_out->data, p_out->linesize);
1992
1993         sws_freeContext(convert_ctx);
1994     }
1995 #endif /* XXX replacement */
1996 }
1997
1998 /*
1999  * Display video frames (from local or remote stream) using the SDL library.
2000  * - Set the video mode to use the resolution specified by the codec context
2001  * - Create a YUV Overlay to copy the frame into it;
2002  * - After the frame is copied into the overlay, display it
2003  *
2004  * The size is taken from the configuration.
2005  *
2006  * 'out' is 0 for remote video, 1 for the local video
2007  */
2008 static void show_frame(struct video_desc *env, int out)
2009 {
2010         AVPicture *p_in, p_out;
2011         struct fbuf_t *b_in, *b_out;
2012         SDL_Overlay *bmp;
2013
2014         if (!env->sdl_ok)
2015                 return;
2016
2017         if (out == WIN_LOCAL) { /* webcam/x11 to sdl */
2018                 b_in = &env->out.enc_in;
2019                 b_out = &env->out.loc_dpy;
2020                 p_in = NULL;
2021         } else {
2022                 /* copy input format from the decoding context */
2023                 AVCodecContext *c = env->in.dec_ctx;
2024                 b_in = &env->in.dec_out;
2025                 b_in->pix_fmt = c->pix_fmt;
2026                 b_in->w = c->width;
2027                 b_in->h = c->height;
2028
2029                 b_out = &env->in.rem_dpy;
2030                 p_in = (AVPicture *)env->in.d_frame;
2031         }
2032         bmp = env->win[out].bmp;
2033         SDL_LockYUVOverlay(bmp);
2034         /* output picture info - this is sdl, YUV420P */
2035         bzero(&p_out, sizeof(p_out));
2036         p_out.data[0] = bmp->pixels[0];
2037         p_out.data[1] = bmp->pixels[1];
2038         p_out.data[2] = bmp->pixels[2];
2039         p_out.linesize[0] = bmp->pitches[0];
2040         p_out.linesize[1] = bmp->pitches[1];
2041         p_out.linesize[2] = bmp->pitches[2];
2042
2043         my_scale(b_in, p_in, b_out, &p_out);
2044
2045         /* lock to protect access to Xlib by different threads. */
2046         SDL_DisplayYUVOverlay(bmp, &env->win[out].rect);
2047         SDL_UnlockYUVOverlay(bmp);
2048 }
2049
2050 struct video_desc *get_video_desc(struct ast_channel *c);
2051
2052 /*
2053  * This function is called (by asterisk) for each video packet
2054  * coming from the network (the 'in' path) that needs to be processed.
2055  * We need to reconstruct the entire video frame before we can decode it.
2056  * After a video packet is received we have to:
2057  * - extract the bitstream with pre_process_data()
2058  * - append the bitstream to a buffer
2059  * - if the fragment is the last (RTP Marker) we decode it with decode_video()
2060  * - after the decoding is completed we display the decoded frame with show_frame()
2061  */
2062 int console_write_video(struct ast_channel *chan, struct ast_frame *f);
2063 int console_write_video(struct ast_channel *chan, struct ast_frame *f)
2064 {
2065         struct video_desc *env = get_video_desc(chan);
2066         struct video_in_desc *v = &env->in;
2067
2068         if (v->dec == NULL) {   /* try to get the codec */
2069                 v->dec = map_video_codec(f->subclass & ~1);
2070                 if (v->dec == NULL) {
2071                         ast_log(LOG_WARNING, "cannot find video codec, drop input 0x%x\n", f->subclass);
2072                         return 0;
2073                 }
2074                 if (video_in_init(v, v->dec->format)) {
2075                         /* This is not fatal, but we won't have incoming video */
2076                         ast_log(LOG_WARNING, "Cannot initialize input decoder\n");
2077                         v->dec = NULL;
2078                         return 0;
2079                 }
2080         }
2081         if (v->dec_ctx == NULL) {
2082                 ast_log(LOG_WARNING, "cannot decode, dropping frame\n");
2083                 return 0;       /* error */
2084         }
2085
2086         if (v->dec_in_cur == NULL)      /* no buffer for incoming frames, drop */
2087                 return 0;
2088 #if defined(DROP_PACKETS) && DROP_PACKETS > 0
2089         /* Simulate lost packets */
2090         if ((random() % 10000) <= 100*DROP_PACKETS) {
2091                 ast_log(LOG_NOTICE, "Packet lost [%d]\n", f->seqno);
2092                 return 0;
2093         }
2094 #endif
2095         if (v->discard) {
2096                 /*
2097                  * In discard mode, drop packets until we find one with
2098                  * the RTP marker set (which is the end of frame).
2099                  * Note that the RTP marker flag is sent as the LSB of the
2100                  * subclass, which is a  bitmask of formats. The low bit is
2101                  * normally used for audio so there is no interference.
2102                  */
2103                 if (f->subclass & 0x01) {
2104                         v->dec_in_cur->used = 0;
2105                         v->dec_in_cur->ebit = 0;
2106                         v->next_seq = f->seqno + 1;     /* wrap at 16 bit */
2107                         v->discard = 0;
2108                         ast_log(LOG_WARNING, "out of discard mode, frame %d\n", f->seqno);
2109                 }
2110                 return 0;
2111         }
2112
2113         /*
2114          * Only in-order fragments will be accepted. Remember seqno
2115          * has 16 bit so there is wraparound. Also, ideally we could
2116          * accept a bit of reordering, but at the moment we don't.
2117          */
2118         if (v->next_seq != f->seqno) {
2119                 ast_log(LOG_WARNING, "discarding frame out of order, %d %d\n",
2120                         v->next_seq, f->seqno);
2121                 v->discard = 1;
2122                 return 0;
2123         }
2124         v->next_seq++;
2125
2126         if (f->data == NULL || f->datalen < 2) {
2127                 ast_log(LOG_WARNING, "empty video frame, discard\n");
2128                 return 0;
2129         }
2130         if (v->dec->dec_decap(v->dec_in_cur, f->data, f->datalen)) {
2131                 ast_log(LOG_WARNING, "error in dec_decap, enter discard\n");
2132                 v->discard = 1;
2133         }
2134         if (f->subclass & 0x01) {       // RTP Marker
2135                 /* prepare to decode: advance the buffer so the video thread knows. */
2136                 struct fbuf_t *tmp = v->dec_in_cur;     /* store current pointer */
2137                 ast_mutex_lock(&v->dec_in_lock);
2138                 if (++v->dec_in_cur == &v->dec_in[N_DEC_IN])    /* advance to next, circular */
2139                         v->dec_in_cur = &v->dec_in[0];
2140                 if (v->dec_in_dpy == NULL) {    /* were not displaying anything, so set it */
2141                         v->dec_in_dpy = tmp;
2142                 } else if (v->dec_in_dpy == v->dec_in_cur) { /* current slot is busy */
2143                         v->dec_in_cur = NULL;
2144                 }
2145                 ast_mutex_unlock(&v->dec_in_lock);
2146         }
2147         return 0;
2148 }
2149
2150
2151 /*! \brief read a frame from webcam or X11 through video_read(),
2152  * display it,  then encode and split it.
2153  * Return a list of ast_frame representing the video fragments.
2154  * The head pointer is returned by the function, the tail pointer
2155  * is returned as an argument.
2156  */
2157 static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_frame **tail)
2158 {
2159         struct video_out_desc *v = &env->out;
2160         struct ast_frame *dummy;
2161
2162         if (!v->loc_src.data) {
2163                 static volatile int a = 0;
2164                 if (a++ < 2)
2165                         ast_log(LOG_WARNING, "fail, no loc_src buffer\n");
2166                 return NULL;
2167         }
2168         if (!video_read(v))
2169                 return NULL;    /* can happen, e.g. we are reading too early */
2170
2171         if (tail == NULL)
2172                 tail = &dummy;
2173         *tail = NULL;
2174         /* Scale the video for the encoder, then use it for local rendering
2175          * so we will see the same as the remote party.
2176          */
2177         my_scale(&v->loc_src, NULL, &v->enc_in, NULL);
2178         show_frame(env, WIN_LOCAL);
2179         if (!v->sendvideo)
2180                 return NULL;
2181         if (v->enc_out.data == NULL) {
2182                 static volatile int a = 0;
2183                 if (a++ < 2)
2184                         ast_log(LOG_WARNING, "fail, no encbuf\n");
2185                 return NULL;
2186         }
2187         v->enc->enc_run(v);
2188         return v->enc->enc_encap(v, tail);
2189 }
2190
2191 /*
2192  * GUI layout, structure and management
2193  *
2194
2195 For the GUI we use SDL to create a large surface (env->screen)
2196 containing tree sections: remote video on the left, local video
2197 on the right, and the keypad with all controls and text windows
2198 in the center.
2199 The central section is built using two images: one is the skin,
2200 the other one is a mask where the sensitive areas of the skin
2201 are colored in different grayscale levels according to their
2202 functions. The mapping between colors and function is defined
2203 in the 'enum pixel_value' below.
2204
2205 Mouse and keyboard events are detected on the whole surface, and
2206 handled differently according to their location, as follows:
2207
2208 - drag on the local video window are used to move the captured
2209   area (in the case of X11 grabber) or the picture-in-picture
2210   location (in case of camera included on the X11 grab).
2211 - click on the keypad are mapped to the corresponding key;
2212 - drag on some keypad areas (sliders etc.) are mapped to the
2213   corresponding functions;
2214 - keystrokes are used as keypad functions, or as text input
2215   if we are in text-input mode.
2216
2217 To manage these behavior we use two status variables,
2218 that defines if keyboard events should be redirect to dialing functions
2219 or to write message functions, and if mouse events should be used
2220 to implement keypad functionalities or to drag the capture device.
2221
2222 Configuration options control the appeareance of the gui:
2223
2224     keypad = /tmp/phone.jpg             ; the keypad on the screen
2225     keypad_font = /tmp/font.ttf         ; the font to use for output
2226
2227  *
2228  */
2229
2230 /* enumerate for the pixel value. 0..127 correspond to ascii chars */
2231 enum pixel_value {
2232         /* answer/close functions */
2233         KEY_PICK_UP = 128,
2234         KEY_HANG_UP = 129,
2235
2236         /* other functions */
2237         KEY_MUTE = 130,
2238         KEY_AUTOANSWER = 131,
2239         KEY_SENDVIDEO = 132,
2240         KEY_LOCALVIDEO = 133,
2241         KEY_REMOTEVIDEO = 134,
2242         KEY_WRITEMESSAGE = 135,
2243         KEY_GUI_CLOSE = 136,            /* close gui */
2244
2245         /* other areas within the keypad */
2246         KEY_DIGIT_BACKGROUND = 255,
2247
2248         /* areas outside the keypad - simulated */
2249         KEY_OUT_OF_KEYPAD = 251,
2250         KEY_REM_DPY = 252,
2251         KEY_LOC_DPY = 253,
2252 };
2253
2254 /*
2255  * Handlers for the various keypad functions
2256  */
2257
2258 /*! \brief append a character, or reset if '\0' */
2259 static void append_char(char *str, int *str_pos, const char c)
2260 {
2261         int i = *str_pos;
2262         if (c == '\0')
2263                 i = 0;
2264         else if (i < GUI_BUFFER_LEN - 1)
2265                 str[i++] = c;
2266         else
2267                 i = GUI_BUFFER_LEN - 1; /* unnecessary, i think */
2268         str = '\0';
2269         *str_pos = i;
2270 }
2271
2272 /* accumulate digits, possibly call dial if in connected mode */
2273 static void keypad_digit(struct video_desc *env, int digit)
2274 {       
2275         if (env->owner) {               /* we have a call, send the digit */
2276                 struct ast_frame f = { AST_FRAME_DTMF, 0 };
2277
2278                 f.subclass = digit;
2279                 ast_queue_frame(env->owner, &f);
2280         } else {                /* no call, accumulate digits */
2281                 append_char(env->gui.inbuf, &env->gui.inbuf_pos, digit);
2282         }
2283 }
2284
2285 /* this is a wrapper for actions that are available through the cli */
2286 /* TODO append arg to command and send the resulting string as cli command */
2287 static void keypad_send_command(struct video_desc *env, char *command)
2288 {       
2289         ast_log(LOG_WARNING, "keypad_send_command(%s) called\n", command);
2290         ast_cli_command(env->gui.outfd, command);
2291         return;
2292 }
2293
2294 /* function used to toggle on/off the status of some variables */
2295 static char *keypad_toggle(struct video_desc *env, int index)
2296 {
2297         ast_log(LOG_WARNING, "keypad_toggle(%i) called\n", index);
2298
2299         switch (index) {
2300         case KEY_SENDVIDEO:
2301                 env->out.sendvideo = !env->out.sendvideo;
2302                 break;
2303 #ifdef notyet
2304         case KEY_MUTE: {
2305                 struct chan_oss_pvt *o = find_desc(oss_active);
2306                 o->mute = !o->mute;
2307                 }
2308                 break;
2309         case KEY_AUTOANSWER: {
2310                 struct chan_oss_pvt *o = find_desc(oss_active);
2311                 o->autoanswer = !o->autoanswer;
2312                 }
2313                 break;
2314 #endif
2315         }
2316         return NULL;
2317 }
2318
2319 char *console_do_answer(int fd);
2320 /*
2321  * Function called when the pick up button is pressed
2322  * perform actions according the channel status:
2323  *
2324  *  - if no one is calling us and no digits was pressed,
2325  *    the operation have no effects,
2326  *  - if someone is calling us we answer to the call.
2327  *  - if we have no call in progress and we pressed some
2328  *    digit, send the digit to the console.
2329  */
2330 static void keypad_pick_up(struct video_desc *env)
2331 {
2332         ast_log(LOG_WARNING, "keypad_pick_up called\n");
2333
2334         if (env->owner) { /* someone is calling us, just answer */
2335                 console_do_answer(-1);
2336         } else if (env->gui.inbuf_pos) { /* we have someone to call */
2337                 ast_cli_command(env->gui.outfd, env->gui.inbuf);
2338         }
2339
2340         append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0'); /* clear buffer */
2341 }
2342
2343 #if 0 /* still unused */
2344 /*
2345  * As an alternative to SDL_TTF, we can simply load the font from
2346  * an image and blit characters on the background of the GUI.
2347  *
2348  * To generate a font we can use the 'fly' command with the
2349  * following script (3 lines with 32 chars each)
2350  
2351 size 320,64
2352 name font.png
2353 transparent 0,0,0
2354 string 255,255,255,  0, 0,giant, !"#$%&'()*+,-./0123456789:;<=>?
2355 string 255,255,255,  0,20,giant,@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_
2356 string 255,255,255,  0,40,giant,`abcdefghijklmnopqrstuvwxyz{|}~
2357 end
2358
2359  */
2360
2361 /* Print given text on the gui */
2362 static int gui_output(struct video_desc *env, const char *text)
2363 {
2364 #ifndef HAVE_SDL_TTF
2365         return 1;       /* error, not supported */
2366 #else
2367         int x = 30, y = 20;     /* XXX change */
2368         SDL_Surface *output = NULL;
2369         SDL_Color color = {0, 0, 0};    /* text color */
2370         SDL_Rect dest = {env->win[WIN_KEYPAD].rect.x + x, y};
2371
2372         /* clean surface each rewrite */
2373         SDL_BlitSurface(env->gui.keypad, NULL, env->screen, &env->win[WIN_KEYPAD].rect);
2374
2375         output = TTF_RenderText_Solid(env->gui.font, text, color);
2376         if (output == NULL) {
2377                 ast_log(LOG_WARNING, "Cannot render text on gui - %s\n", TTF_GetError());
2378                 return 1;
2379         }
2380
2381         SDL_BlitSurface(output, NULL, env->screen, &dest);
2382         
2383         SDL_UpdateRects(env->gui.keypad, 1, &env->win[WIN_KEYPAD].rect);
2384         SDL_FreeSurface(output);
2385         return 0;       /* success */
2386 #endif
2387 }
2388 #endif 
2389
2390 static int video_geom(struct fbuf_t *b, const char *s);
2391 static void sdl_setup(struct video_desc *env);
2392 static int kp_match_area(const struct keypad_entry *e, int x, int y);
2393
2394 /*
2395  * Handle SDL_MOUSEBUTTONDOWN type, finding the palette
2396  * index value and calling the right callback.
2397  *
2398  * x, y are referred to the upper left corner of the main SDL window.
2399  */
2400 static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent button)
2401 {
2402         uint8_t index = KEY_OUT_OF_KEYPAD;      /* the key or region of the display we clicked on */
2403
2404         /* for each click we come back in normal mode */
2405         env->gui.text_mode = 0;
2406
2407         /* define keypad boundary */
2408         if (button.x < env->in.rem_dpy.w)
2409                 index = KEY_REM_DPY; /* click on remote video */
2410         else if (button.x > env->in.rem_dpy.w + env->out.keypad_dpy.w)
2411                 index = KEY_LOC_DPY; /* click on local video */
2412         else if (button.y > env->out.keypad_dpy.h)
2413                 index = KEY_OUT_OF_KEYPAD; /* click outside the keypad */
2414         else if (env->gui.kp) {
2415                 int i;
2416                 for (i = 0; i < env->gui.kp_used; i++) {
2417                         if (kp_match_area(&env->gui.kp[i], button.x - env->in.rem_dpy.w, button.y)) {
2418                                 index = env->gui.kp[i].c;
2419                                 break;
2420                         }
2421                 }
2422         }
2423
2424         /* exec the function */
2425         if (index < 128) {      /* surely clicked on the keypad, don't care which key */
2426                 keypad_digit(env, index);
2427                 return;
2428         }
2429         switch (index) {
2430         /* answer/close function */
2431         case KEY_PICK_UP:
2432                 keypad_pick_up(env);
2433                 break;
2434         case KEY_HANG_UP:
2435                 keypad_send_command(env, "console hangup");
2436                 break;
2437
2438         /* other functions */
2439         case KEY_MUTE:
2440         case KEY_AUTOANSWER:
2441         case KEY_SENDVIDEO:
2442                 keypad_toggle(env, index);
2443                 break;
2444
2445         case KEY_LOCALVIDEO:
2446                 break;
2447         case KEY_REMOTEVIDEO:
2448                 break;
2449         case KEY_WRITEMESSAGE:
2450                 /* goes in text-mode */
2451                 env->gui.text_mode = 1;
2452                 break;
2453
2454
2455         /* press outside the keypad. right increases size, center decreases, left drags */
2456         case KEY_LOC_DPY:
2457         case KEY_REM_DPY:
2458                 if (button.button == SDL_BUTTON_LEFT) {
2459                         if (index == KEY_LOC_DPY) {
2460                                 /* store points where the drag start
2461                                 * and switch in drag mode */
2462                                 env->gui.x_drag = button.x;
2463                                 env->gui.y_drag = button.y;
2464                                 env->gui.drag_mode = 1;
2465                         }
2466                         break;
2467                 } else {
2468                         char buf[128];
2469                         struct fbuf_t *fb = index == KEY_LOC_DPY ? &env->out.loc_dpy : &env->in.rem_dpy;
2470                         sprintf(buf, "%c%dx%d", button.button == SDL_BUTTON_RIGHT ? '>' : '<',
2471                                 fb->w, fb->h);
2472                         video_geom(fb, buf);
2473                         sdl_setup(env);
2474                 }
2475                 break;
2476         case KEY_OUT_OF_KEYPAD:
2477                 break;
2478
2479         case KEY_GUI_CLOSE:
2480                 cleanup_sdl(env);
2481                 break;
2482         case KEY_DIGIT_BACKGROUND:
2483                 break;
2484         default:
2485                 ast_log(LOG_WARNING, "function not yet defined %i\n", index);
2486         }
2487 }
2488
2489 /*
2490  * Handle SDL_KEYDOWN type event, put the key pressed
2491  * in the dial buffer or in the text-message buffer,
2492  * depending on the text_mode variable value.
2493  *
2494  * key is the SDLKey structure corresponding to the key pressed.
2495  */
2496 static void handle_keyboard_input(struct video_desc *env, SDLKey key)
2497 {
2498         if (env->gui.text_mode) {
2499                 /* append in the text-message buffer */
2500                 if (key == SDLK_RETURN) {
2501                         /* send the text message and return in normal mode */
2502                         env->gui.text_mode = 0;
2503                         keypad_send_command(env, "send text");
2504                 } else {
2505                         /* accumulate the key in the message buffer */
2506                         append_char(env->gui.msgbuf, &env->gui.msgbuf_pos, key);
2507                 }
2508         }
2509         else {
2510                 /* append in the dial buffer */
2511                 append_char(env->gui.inbuf, &env->gui.inbuf_pos, key);
2512         }
2513
2514         return;
2515 }
2516
2517 /*
2518  * Check if the grab point is inside the X screen.
2519  *
2520  * x represent the new grab value
2521  * limit represent the upper value to use
2522  */
2523 static int boundary_checks(int x, int limit)
2524 {
2525         return (x <= 0) ? 0 : (x > limit ? limit : x);
2526 }
2527
2528 /* implement superlinear acceleration on the movement */
2529 static int move_accel(int delta)
2530 {
2531         int d1 = delta*delta / 100;
2532         return (delta > 0) ? delta + d1 : delta - d1;
2533 }
2534
2535 /*
2536  * Move the source of the captured video.
2537  *
2538  * x_final_drag and y_final_drag are the coordinates where the drag ends,
2539  * start coordinares are in the gui_info structure.
2540  */
2541 static void move_capture_source(struct video_desc *env, int x_final_drag, int y_final_drag)
2542 {
2543         int new_x, new_y;               /* new coordinates for grabbing local video */
2544         int x = env->out.loc_src.x;     /* old value */
2545         int y = env->out.loc_src.y;     /* old value */
2546
2547         /* move the origin */
2548 #define POLARITY -1             /* +1 or -1 depending on the desired direction */
2549         new_x = x + POLARITY*move_accel(x_final_drag - env->gui.x_drag) * 3;
2550         new_y = y + POLARITY*move_accel(y_final_drag - env->gui.y_drag) * 3;
2551 #undef POLARITY
2552         env->gui.x_drag = x_final_drag; /* update origin */
2553         env->gui.y_drag = y_final_drag;
2554
2555         /* check boundary and let the source to grab from the new points */
2556         env->out.loc_src.x = boundary_checks(new_x, env->out.screen_width - env->out.loc_src.w);
2557         env->out.loc_src.y = boundary_checks(new_y, env->out.screen_height - env->out.loc_src.h);
2558         return;
2559 }
2560
2561 /*
2562  * I am seeing some kind of deadlock or stall around
2563  * SDL_PumpEvents() while moving the window on a remote X server
2564  * (both xfree-4.4.0 and xorg 7.2)
2565  * and windowmaker. It is unclear what causes it.
2566  */
2567
2568 /* grab a bunch of events */
2569 static void eventhandler(struct video_desc *env)
2570 {
2571 #define N_EVENTS        32
2572         int i, n;
2573         SDL_Event ev[N_EVENTS];
2574
2575 #define MY_EV (SDL_MOUSEBUTTONDOWN|SDL_KEYDOWN)
2576         while ( (n = SDL_PeepEvents(ev, N_EVENTS, SDL_GETEVENT, SDL_ALLEVENTS)) > 0) {
2577                 for (i = 0; i < n; i++) {
2578 #if 0
2579                         ast_log(LOG_WARNING, "------ event %d at %d %d\n",
2580                                 ev[i].type,  ev[i].button.x,  ev[i].button.y);
2581 #endif
2582                         switch (ev[i].type) {
2583                         case SDL_KEYDOWN:
2584                                 handle_keyboard_input(env, ev[i].key.keysym.sym);
2585                                 break;
2586                         case SDL_MOUSEMOTION:
2587                                 if (env->gui.drag_mode != 0)
2588                                         move_capture_source(env, ev[i].motion.x, ev[i].motion.y);
2589                                 break;
2590                         case SDL_MOUSEBUTTONDOWN:
2591                                 handle_button_event(env, ev[i].button);
2592                                 break;
2593                         case SDL_MOUSEBUTTONUP:
2594                                 if (env->gui.drag_mode != 0) {
2595                                         move_capture_source(env, ev[i].button.x, ev[i].button.y);
2596                                         env->gui.drag_mode = 0;
2597                                 }
2598                                 break;
2599                         }
2600
2601                 }
2602         }
2603         if (1) {
2604                 struct timeval b, a = ast_tvnow();
2605                 int i;
2606                 //SDL_Lock_EventThread();
2607                 SDL_PumpEvents();
2608                 b = ast_tvnow();
2609                 i = ast_tvdiff_ms(b, a);
2610                 if (i > 3)
2611                         fprintf(stderr, "-------- SDL_PumpEvents took %dms\n", i);
2612                 //SDL_Unlock_EventThread();
2613         }
2614 }
2615
2616 static SDL_Surface *get_keypad(const char *file)
2617 {
2618         SDL_Surface *temp;
2619  
2620 #ifdef HAVE_SDL_IMAGE
2621         temp = IMG_Load(file);
2622 #else
2623         temp = SDL_LoadBMP(file);
2624 #endif
2625         if (temp == NULL)
2626                 fprintf(stderr, "Unable to load image %s: %s\n",
2627                         file, SDL_GetError());
2628         return temp;
2629 }
2630
2631 /* TODO: consistency checks, check for bpp, widht and height */
2632 /* Init the mask image used to grab the action. */
2633 static int gui_init(struct video_desc *env)
2634 {
2635         /* initialize keypad status */
2636         env->gui.text_mode = 0;
2637         env->gui.drag_mode = 0;
2638
2639         /* initialize grab coordinates */
2640         env->out.loc_src.x = 0;
2641         env->out.loc_src.y = 0;
2642
2643         /* initialize keyboard buffer */
2644         append_char(env->gui.inbuf, &env->gui.inbuf_pos, '\0');
2645         append_char(env->gui.msgbuf, &env->gui.msgbuf_pos, '\0');
2646
2647 #ifdef HAVE_SDL_TTF
2648         /* Initialize SDL_ttf library and load font */
2649         if (TTF_Init() == -1) {
2650                 ast_log(LOG_WARNING, "Unable to init SDL_ttf, no output available\n");
2651                 return -1;
2652         }
2653
2654 #define GUI_FONTSIZE 28
2655         env->gui.font = TTF_OpenFont( env->keypad_font, GUI_FONTSIZE);
2656         if (!env->gui.font) {
2657                 ast_log(LOG_WARNING, "Unable to load font %s, no output available\n", env->keypad_font);
2658                 return -1;
2659         }
2660         ast_log(LOG_WARNING, "Loaded font %s\n", env->keypad_font);
2661 #endif
2662
2663         env->gui.outfd = open ("/dev/null", O_WRONLY);  /* discard output, temporary */
2664         if ( env->gui.outfd < 0 ) {
2665                 ast_log(LOG_WARNING, "Unable output fd\n");
2666                 return -1;
2667         }
2668
2669         return 0;
2670 }
2671
2672 static void sdl_setup(struct video_desc *env);
2673
2674 /*
2675  * Helper thread to periodically poll the video source and enqueue the
2676  * generated frames to the channel's queue.
2677  * Using a separate thread also helps because the encoding can be
2678  * computationally expensive so we don't want to starve the main thread.
2679  */
2680 static void *video_thread(void *arg)
2681 {
2682         struct video_desc *env = arg;
2683         int count = 0;
2684         char save_display[128] = "";
2685
2686         env->screen = NULL;
2687         bzero(env->win, sizeof(env->win));
2688
2689         /* if sdl_videodriver is set, override the environment. Also,
2690          * if it contains 'console' override DISPLAY around the call to SDL_Init
2691          * so we use the console as opposed to the x11 version of aalib
2692          */
2693         if (!ast_strlen_zero(env->sdl_videodriver)) { /* override */
2694                 const char *s = getenv("DISPLAY");
2695                 setenv("SDL_VIDEODRIVER", env->sdl_videodriver, 1);
2696                 if (s && !strcasecmp(env->sdl_videodriver, "aalib-console")) {
2697                         ast_copy_string(save_display, s, sizeof(save_display));
2698                         unsetenv("DISPLAY");
2699                 }
2700         }
2701         if (SDL_Init(SDL_INIT_VIDEO)) {
2702                 ast_log(LOG_WARNING, "Could not initialize SDL - %s\n",
2703                         SDL_GetError());
2704                 /* again not fatal, just we won't display anything */
2705         } else {
2706                 sdl_setup(env);
2707                 if (env->sdl_ok)
2708                         ast_mutex_init(&env->in.dec_in_lock);
2709                 /* TODO, segfault if not X display present */
2710                 env->gui_ok = !gui_init(env);
2711                 if (!env->gui_ok)
2712                         ast_log(LOG_WARNING, "cannot init console gui\n");
2713         }
2714         if (!ast_strlen_zero(save_display))
2715                 setenv("DISPLAY", save_display, 1);
2716
2717         if (video_open(&env->out)) {
2718                 ast_log(LOG_WARNING, "cannot open local video source\n");
2719         } else {
2720                 /* try to register the fd. Unfortunately, if the webcam
2721                  * driver does not support select/poll we are out of luck.
2722                  */
2723                 if (env->out.fd >= 0)
2724                         ast_channel_set_fd(env->owner, 1, env->out.fd);
2725                 video_out_init(env);
2726         }
2727
2728         for (;;) {
2729                 /* XXX 20 times/sec */
2730                 struct timeval t = { 0, 50000 };
2731                 struct ast_frame *p, *f;
2732                 struct video_in_desc *v = &env->in;
2733                 struct ast_channel *chan = env->owner;
2734                 int fd = chan->alertpipe[1];
2735
2736                 /* determine if video format changed */
2737                 if (count++ % 10 == 0) {
2738                         char buf[160];
2739                         if (env->out.sendvideo)
2740                             sprintf(buf, "%s %s %dx%d @@ %dfps %dkbps",
2741                                 env->out.videodevice, env->codec_name,
2742                                 env->out.enc_in.w, env->out.enc_in.h,
2743                                 env->out.fps, env->out.bitrate/1000);
2744                         else
2745                             sprintf(buf, "hold");
2746                         SDL_WM_SetCaption(buf, NULL);
2747                 }
2748
2749                 /* manage keypad events */
2750                 /* XXX here we should always check for events,
2751                 * otherwise the drag will not work */ 
2752                 if (env->gui_ok)
2753                         eventhandler(env);
2754  
2755                 /* sleep for a while */
2756                 ast_select(0, NULL, NULL, NULL, &t);
2757
2758                 SDL_UpdateRects(env->screen, 1, &env->win[WIN_KEYPAD].rect);// XXX inefficient
2759                 /*
2760                  * While there is something to display, call the decoder and free
2761                  * the buffer, possibly enabling the receiver to store new data.
2762                  */
2763                 while (v->dec_in_dpy) {
2764                         struct fbuf_t *tmp = v->dec_in_dpy;     /* store current pointer */
2765
2766                         if (v->dec->dec_run(v, tmp))
2767                                 show_frame(env, WIN_REMOTE);
2768                         tmp->used = 0;  /* mark buffer as free */
2769                         tmp->ebit = 0;
2770                         ast_mutex_lock(&v->dec_in_lock);
2771                         if (++v->dec_in_dpy == &v->dec_in[N_DEC_IN])    /* advance to next, circular */
2772                                 v->dec_in_dpy = &v->dec_in[0];
2773
2774                         if (v->dec_in_cur == NULL)      /* receiver was idle, enable it... */
2775                                 v->dec_in_cur = tmp;    /* using the slot just freed */
2776                         else if (v->dec_in_dpy == v->dec_in_cur) /* this was the last slot */
2777                                 v->dec_in_dpy = NULL;   /* nothing more to display */
2778                         ast_mutex_unlock(&v->dec_in_lock);
2779                 }
2780
2781
2782                 f = get_video_frames(env, &p);  /* read and display */
2783                 if (!f)
2784                         continue;
2785                 if (env->shutdown)
2786                         break;
2787                 chan = env->owner;
2788                 ast_channel_lock(chan);
2789
2790                 /* AST_LIST_INSERT_TAIL is only good for one frame, cannot use here */
2791                 if (chan->readq.first == NULL) {
2792                         chan->readq.first = f;
2793                 } else {
2794                         chan->readq.last->frame_list.next = f;
2795                 }
2796                 chan->readq.last = p;
2797                 /*
2798                  * more or less same as ast_queue_frame, but extra
2799                  * write on the alertpipe to signal frames.
2800                  */
2801                 if (fd > -1) {
2802                         int blah = 1, l = sizeof(blah);
2803                         for (p = f; p; p = AST_LIST_NEXT(p, frame_list)) {
2804                                 if (write(fd, &blah, l) != l)
2805                                         ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d: %s!\n",
2806                                             chan->name, f->frametype, f->subclass, strerror(errno));
2807                         }
2808                 }
2809                 ast_channel_unlock(chan);
2810         }
2811         /* thread terminating, here could call the uninit */
2812         /* uninitialize the local and remote video environments */
2813         video_in_uninit(&env->in);
2814         video_out_uninit(&env->out);
2815
2816         if (env->sdl_ok)
2817                 cleanup_sdl(env);
2818
2819         env->shutdown = 0;
2820         return NULL;
2821 }
2822
2823 static void copy_geometry(struct fbuf_t *src, struct fbuf_t *dst)
2824 {
2825         if (dst->w == 0)
2826                 dst->w = src->w;
2827         if (dst->h == 0)
2828                 dst->h = src->h;
2829 }
2830
2831 /*! initialize the video environment.
2832  * Apart from the formats (constant) used by sdl and the codec,
2833  * we use enc_in as the basic geometry.
2834  */
2835 static void init_env(struct video_desc *env)
2836 {
2837         struct fbuf_t *c = &(env->out.loc_src);         /* local source */
2838         struct fbuf_t *ei = &(env->out.enc_in);         /* encoder input */
2839         struct fbuf_t *ld = &(env->out.loc_dpy);        /* local display */
2840         struct fbuf_t *rd = &(env->in.rem_dpy);         /* remote display */
2841
2842         c->pix_fmt = PIX_FMT_YUV420P;   /* default - camera format */
2843         ei->pix_fmt = PIX_FMT_YUV420P;  /* encoder input */
2844         if (ei->w == 0 || ei->h == 0) {
2845                 ei->w = 352;
2846                 ei->h = 288;
2847         }
2848         ld->pix_fmt = rd->pix_fmt = PIX_FMT_YUV420P; /* sdl format */
2849         /* inherit defaults */
2850         copy_geometry(ei, c);   /* camera inherits from encoder input */
2851         copy_geometry(ei, rd);  /* remote display inherits from encoder input */
2852         copy_geometry(rd, ld);  /* local display inherits from remote display */
2853 }
2854
2855 /* setup an sdl overlay and associated info, return 0 on success, != 0 on error */
2856 static int set_win(SDL_Surface *screen, struct display_window *win, int fmt,
2857         int w, int h, int x, int y)
2858 {
2859         win->bmp = SDL_CreateYUVOverlay(w, h, fmt, screen);
2860         if (win->bmp == NULL)
2861                 return -1;      /* error */
2862         win->rect.x = x;
2863         win->rect.y = y;
2864         win->rect.w = w;
2865         win->rect.h = h;
2866         return 0;
2867 }
2868
2869 /*!
2870  * The first call to the video code, called by oss_new() or similar.
2871  * Here we initialize the various components we use, namely SDL for display,
2872  * ffmpeg for encoding/decoding, and a local video source.
2873  * We do our best to progress even if some of the components are not
2874  * available.
2875  */
2876 void console_video_start(struct video_desc *env, struct ast_channel *owner)
2877 {
2878         if (env == NULL)        /* video not initialized */
2879                 return;
2880         if (owner == NULL)      /* nothing to do if we don't have a channel */
2881                 return;
2882         env->owner = owner;
2883         init_env(env);
2884         env->out.enc = map_config_video_format(env->codec_name);
2885
2886         ast_log(LOG_WARNING, "start video out %s %dx%d\n",
2887                 env->codec_name, env->out.enc_in.w,  env->out.enc_in.h);
2888         /*
2889          * Register all codecs supported by the ffmpeg library.
2890          * We only need to do it once, but probably doesn't
2891          * harm to do it multiple times.
2892          */
2893         avcodec_init();
2894         avcodec_register_all();
2895         av_log_set_level(AV_LOG_ERROR); /* only report errors */
2896
2897         if (env->out.fps == 0) {
2898                 env->out.fps = 15;
2899                 ast_log(LOG_WARNING, "fps unset, forcing to %d\n", env->out.fps);
2900         }
2901         if (env->out.bitrate == 0) {
2902                 env->out.bitrate = 65000;
2903                 ast_log(LOG_WARNING, "bitrate unset, forcing to %d\n", env->out.bitrate);
2904         }
2905
2906         ast_pthread_create_background(&env->vthread, NULL, video_thread, env);
2907 }
2908
2909 static int keypad_cfg_read(struct gui_info *gui, const char *val);
2910
2911 static void keypad_setup(struct video_desc *env)
2912 {
2913         int fd = -1;
2914         void *p = NULL;
2915         off_t l = 0;
2916
2917         if (env->gui.keypad)
2918                 return;
2919         env->gui.keypad = get_keypad(env->keypad_file);
2920         if (!env->gui.keypad)
2921                 return;
2922
2923         env->out.keypad_dpy.w = env->gui.keypad->w;
2924         env->out.keypad_dpy.h = env->gui.keypad->h;
2925         /*
2926          * If the keypad image has a comment field, try to read
2927          * the button location from there. The block must be
2928          *      keypad_entry = token shape x0 y0 x1 y1 h
2929          *      ...
2930          * (basically, lines have the same format as config file entries.
2931          * same as the keypad_entry.
2932          * You can add it to a jpeg file using wrjpgcom
2933          */
2934         do { /* only once, in fact */
2935                 const char region[] = "region";
2936                 int reg_len = strlen(region);
2937                 const unsigned char *s, *e;
2938
2939                 fd = open(env->keypad_file, O_RDONLY);
2940                 if (fd < 0) {
2941                         ast_log(LOG_WARNING, "fail to open %s\n", env->keypad_file);
2942                         break;
2943                 }
2944                 l = lseek(fd, 0, SEEK_END);
2945                 if (l <= 0) {
2946                         ast_log(LOG_WARNING, "fail to lseek %s\n", env->keypad_file);
2947                         break;
2948                 }
2949                 p = mmap(NULL, l, PROT_READ, 0, fd, 0);
2950                 if (p == NULL) {
2951                         ast_log(LOG_WARNING, "fail to mmap %s size %ld\n", env->keypad_file, (long)l);
2952                         break;
2953                 }
2954                 e = (const unsigned char *)p + l;
2955                 for (s = p; s < e - 20 ; s++) {
2956                         if (!memcmp(s, region, reg_len)) { /* keyword found */
2957                                 /* reset previous entries */
2958                                 keypad_cfg_read(&env->gui, "reset");
2959                                 break;
2960                         }
2961                 }
2962                 for ( ;s < e - 20; s++) {
2963                         char buf[256];
2964                         const unsigned char *s1;
2965                         if (index(" \t\r\n", *s))       /* ignore blanks */
2966                                 continue;
2967                         if (*s > 127)   /* likely end of comment */
2968                                 break;
2969                         if (memcmp(s, region, reg_len)) /* keyword not found */
2970                                 break;
2971                         s += reg_len;
2972                         l = MIN(sizeof(buf), e - s);
2973                         ast_copy_string(buf, s, l);
2974                         s1 = ast_skip_blanks(buf);      /* between token and '=' */
2975                         if (*s1++ != '=')       /* missing separator */
2976                                 break;
2977                         if (*s1 == '>') /* skip => */
2978                                 s1++;
2979                         keypad_cfg_read(&env->gui, ast_skip_blanks(s1));
2980                         /* now wait for a newline */
2981                         s1 = s;
2982                         while (s1 < e - 20 && !index("\r\n", *s1) && *s1 < 128)
2983                                 s1++;
2984                         s = s1;
2985                 }
2986         } while (0);
2987         if (p)
2988                 munmap(p, l);
2989         if (fd >= 0)
2990                 close(fd);
2991 }
2992
2993 /* [re]set the main sdl window, useful in case of resize */
2994 static void sdl_setup(struct video_desc *env)
2995 {
2996         int dpy_fmt = SDL_IYUV_OVERLAY; /* YV12 causes flicker in SDL */
2997         int depth, maxw, maxh;
2998         const SDL_VideoInfo *info = SDL_GetVideoInfo();
2999
3000         /* We want at least 16bpp to support YUV overlays.
3001          * E.g with SDL_VIDEODRIVER = aalib the default is 8
3002          */
3003         depth = info->vfmt->BitsPerPixel;
3004         if (depth < 16)
3005                 depth = 16;
3006         /*
3007          * initialize the SDL environment. We have one large window
3008          * with local and remote video, and a keypad.
3009          * At the moment we arrange them statically, as follows:
3010          * - on the left, the remote video;
3011          * - on the center, the keypad
3012          * - on the right, the local video
3013          */
3014
3015         keypad_setup(env);
3016 #define BORDER  5       /* border around our windows */
3017         maxw = env->in.rem_dpy.w + env->out.loc_dpy.w + env->out.keypad_dpy.w;
3018         maxh = MAX( MAX(env->in.rem_dpy.h, env->out.loc_dpy.h), env->out.keypad_dpy.h);
3019         maxw += 4 * BORDER;
3020         maxh += 2 * BORDER;
3021         env->screen = SDL_SetVideoMode(maxw, maxh, depth, 0);
3022         if (!env->screen) {
3023                 ast_log(LOG_ERROR, "SDL: could not set video mode - exiting\n");
3024                 goto no_sdl;
3025         }
3026
3027         SDL_WM_SetCaption("Asterisk console Video Output", NULL);
3028         if (set_win(env->screen, &env->win[WIN_REMOTE], dpy_fmt,
3029                         env->in.rem_dpy.w, env->in.rem_dpy.h, BORDER, BORDER))
3030                 goto no_sdl;
3031         if (set_win(env->screen, &env->win[WIN_LOCAL], dpy_fmt,
3032                         env->out.loc_dpy.w, env->out.loc_dpy.h,
3033                         3*BORDER+env->in.rem_dpy.w + env->out.keypad_dpy.w, BORDER))
3034                 goto no_sdl;
3035
3036         /* display the skin, but do not free it as we need it later to
3037          * restore text areas and maybe sliders too.
3038          */
3039         if (env->gui.keypad) {
3040                 struct SDL_Rect *dest = &env->win[WIN_KEYPAD].rect;
3041                 dest->x = 2*BORDER + env->in.rem_dpy.w;
3042                 dest->y = BORDER;
3043                 dest->w = env->gui.keypad->w;
3044                 dest->h = env->gui.keypad->h;
3045                 SDL_BlitSurface(env->gui.keypad, NULL, env->screen, dest);
3046                 SDL_UpdateRects(env->screen, 1, dest);
3047         }
3048         env->in.dec_in_cur = &env->in.dec_in[0];
3049         env->in.dec_in_dpy = NULL;      /* nothing to display */
3050         env->sdl_ok = 1;
3051
3052 no_sdl:
3053         if (env->sdl_ok == 0)   /* free resources in case of errors */
3054                 cleanup_sdl(env);
3055 }
3056
3057 /*
3058  * Parse a geometry string, accepting also common names for the formats.
3059  * Trick: if we have a leading > or < and a numeric geometry,
3060  * return the larger or smaller one.
3061  * E.g. <352x288 gives the smaller one, 320x240
3062  */
3063 static int video_geom(struct fbuf_t *b, const char *s)
3064 {
3065         int w = 0, h = 0;
3066
3067         static struct {
3068                 const char *s; int w; int h;
3069         } *fp, formats[] = {
3070                 {"vga",         640, 480 },
3071                 {"cif",         352, 288 },
3072                 {"qvga",        320, 240 },
3073                 {"qcif",        176, 144 },
3074                 {"sqcif",       128, 96 },
3075                 {NULL,          0, 0 },
3076         };
3077         if (*s == '<' || *s == '>')
3078                 sscanf(s+1,"%dx%d", &w, &h);
3079         for (fp = formats; fp->s; fp++) {
3080                 if (*s == '>') {        /* look for a larger one */
3081                         if (fp->w <= w) {
3082                                 if (fp > formats)
3083                                         fp--; /* back one step if possible */
3084                                 break;
3085                         }
3086                 } else if (*s == '<') { /* look for a smaller one */
3087                         if (fp->w < w)
3088                                 break;
3089                 } else if (!strcasecmp(s, fp->s)) { /* look for a string */
3090                         break;
3091                 }
3092         }
3093         if (*s == '<' && fp->s == NULL) /* smallest */
3094                 fp--;
3095         if (fp->s) {
3096                 b->w = fp->w;
3097                 b->h = fp->h;
3098         } else if (sscanf(s, "%dx%d", &b->w, &b->h) != 2) {
3099                 ast_log(LOG_WARNING, "Invalid video_size %s, using 352x288\n", s);
3100                 b->w = 352;
3101                 b->h = 288;
3102         }
3103         return 0;
3104 }
3105
3106 /*
3107  * Functions to determine if a point is within a region. Return 1 if success.
3108  * First rotate the point, with
3109  *      x' =  (x - x0) * cos A + (y - y0) * sin A
3110  *      y' = -(x - x0) * sin A + (y - y0) * cos A
3111  * where cos A = (x1-x0)/l, sin A = (y1 - y0)/l, and
3112  *      l = sqrt( (x1-x0)^2 + (y1-y0)^2
3113  * Then determine inclusion by simple comparisons i.e.:
3114  *      rectangle: x >= 0 && x < l && y >= 0 && y < h
3115  *      ellipse: (x-xc)^2/l^2 + (y-yc)^2/h2 < 1
3116  */
3117 static int kp_match_area(const struct keypad_entry *e, int x, int y)
3118 {
3119         double xp, dx = (e->x1 - e->x0);
3120         double yp, dy = (e->y1 - e->y0);
3121         double l = sqrt(dx*dx + dy*dy);
3122         int ret = 0;
3123
3124         if (l > 1) { /* large enough */
3125                 xp = ((x - e->x0)*dx + (y - e->y0)*dy)/l;
3126                 yp = (-(x - e->x0)*dy + (y - e->y0)*dx)/l;
3127                 if (e->type == KP_RECT) {
3128                         ret = (xp >= 0 && xp < l && yp >=0 && yp < l);
3129                 } else if (e->type == KP_CIRCLE) {
3130                         dx = xp*xp/(l*l) + yp*yp/(e->h*e->h);
3131                         ret = (dx < 1);
3132                 }
3133         }
3134 #if 0
3135         ast_log(LOG_WARNING, "result %d [%d] for match %d,%d in type %d p0 %d,%d p1 %d,%d h %d\n",
3136                 ret, e->c, x, y, e->type, e->x0, e->y0, e->x1, e->y1, e->h);
3137 #endif
3138         return ret;
3139 }
3140
3141 /*
3142  * read a keypad entry line in the format
3143  *      reset
3144  *      token circle xc yc diameter
3145  *      token circle xc yc x1 y1 h      # ellipse, main diameter and height
3146  *      token rect x0 y0 x1 y1 h        # rectangle with main side and eight
3147  * token is the token to be returned, either a character or a symbol
3148  * as KEY_* above
3149  */
3150 struct _s_k { const char *s; int k; };
3151 static struct _s_k gui_key_map[] = {
3152         {"PICK_UP",     KEY_PICK_UP },
3153         {"PICKUP",      KEY_PICK_UP },
3154         {"HANG_UP",     KEY_HANG_UP },
3155         {"HANGUP",      KEY_HANG_UP },
3156         {"MUTE",        KEY_MUTE },
3157         {"AUTOANSWER",  KEY_AUTOANSWER },
3158         {"SENDVIDEO",   KEY_SENDVIDEO },
3159         {"LOCALVIDEO",  KEY_LOCALVIDEO },
3160         {"REMOTEVIDEO", KEY_REMOTEVIDEO },
3161         {"WRITEMESSAGE", KEY_WRITEMESSAGE },
3162         {"GUI_CLOSE",   KEY_GUI_CLOSE },
3163         {NULL, 0 } };
3164
3165 static int keypad_cfg_read(struct gui_info *gui, const char *val)
3166 {
3167         struct keypad_entry e;
3168         char s1[16], s2[16];
3169         int i, ret = 0;
3170
3171         bzero(&e, sizeof(e));
3172         i = sscanf(val, "%14s %14s %d %d %d %d %d",
3173                 s1, s2, &e.x0, &e.y0, &e.x1, &e.y1, &e.h);
3174
3175         switch (i) {
3176         default:
3177                 break;
3178         case 1: /* only "reset" is allowed */
3179                 if (strcasecmp(s1, "reset"))    /* invalid */
3180                         break;
3181                 if (gui->kp) {
3182                         gui->kp_used = 0;
3183                 }
3184                 break;
3185         case 5: /* token circle xc yc diameter */
3186                 if (strcasecmp(s2, "circle"))   /* invalid */
3187                         break;
3188                 e.h = e.x1;
3189                 e.y1 = e.y0;    /* map radius in x1 y1 */
3190                 e.x1 = e.x0 + e.h;      /* map radius in x1 y1 */
3191                 e.x0 = e.x0 - e.h;      /* map radius in x1 y1 */
3192                 /* fallthrough */
3193
3194         case 7: /* token circle|rect x0 y0 x1 y1 h */
3195                 if (e.x1 < e.x0 || e.h <= 0) {
3196                         ast_log(LOG_WARNING, "error in coordinates\n");
3197                         e.type = 0;
3198                         break;
3199                 }
3200                 if (!strcasecmp(s2, "circle")) {
3201                         /* for a circle we specify the diameter but store center and radii */
3202                         e.type = KP_CIRCLE;
3203                         e.x0 = (e.x1 + e.x0) / 2;
3204                         e.y0 = (e.y1 + e.y0) / 2;
3205                         e.h = e.h / 2;
3206                 } else if (!strcasecmp(s2, "rect")) {
3207                         e.type = KP_RECT;
3208                 } else
3209                         break;
3210                 ret = 1;
3211         }
3212         // ast_log(LOG_WARNING, "reading [%s] returns %d %d\n", val, i, ret);
3213         if (ret == 0)
3214                 return 0;
3215         /* map the string into token to be returned */
3216         i = atoi(s1);
3217         if (i > 0 || s1[1] == '\0')     /* numbers or single characters */
3218                 e.c = (i > 9) ? i : s1[0];
3219         else {
3220                 struct _s_k *p;
3221                 for (p = gui_key_map; p->s; p++) {
3222                         if (!strcasecmp(p->s, s1)) {
3223                                 e.c = p->k;
3224                                 break;
3225                         }
3226                 }
3227         }
3228         if (e.c == 0) {
3229                 ast_log(LOG_WARNING, "missing token\n");
3230                 return 0;
3231         }
3232         if (gui->kp_size == 0) {
3233                 gui->kp = ast_calloc(10, sizeof(e));
3234                 if (gui->kp == NULL) {
3235                         ast_log(LOG_WARNING, "cannot allocate kp");
3236                         return 0;
3237                 }
3238                 gui->kp_size = 10;
3239         }
3240         if (gui->kp_size == gui->kp_used) { /* must allocate */
3241                 struct keypad_entry *a = ast_realloc(gui->kp, sizeof(e)*(gui->kp_size+10));
3242                 if (a == NULL) {
3243                         ast_log(LOG_WARNING, "cannot reallocate kp");
3244                         return 0;
3245                 }
3246                 gui->kp = a;
3247                 gui->kp_size += 10;
3248         }
3249         if (gui->kp_size == gui->kp_used)
3250                 return 0;
3251         gui->kp[gui->kp_used++] = e;
3252         return 1;
3253 }
3254
3255 /* extend ast_cli with video commands. Called by console_video_config */
3256 int console_video_cli(struct video_desc *env, const char *var, int fd)
3257 {
3258         if (env == NULL)
3259                 return 1;       /* unrecognised */
3260
3261         if (!strcasecmp(var, "videodevice")) {
3262                 ast_cli(fd, "videodevice is [%s]\n", env->out.videodevice);
3263         } else if (!strcasecmp(var, "videocodec")) {
3264                 ast_cli(fd, "videocodec is [%s]\n", env->codec_name);
3265         } else if (!strcasecmp(var, "sendvideo")) {
3266                 ast_cli(fd, "sendvideo is [%s]\n", env->out.sendvideo ? "on" : "off");
3267         } else if (!strcasecmp(var, "video_size")) {
3268                 ast_cli(fd, "sizes: video %dx%d camera %dx%d local %dx%d remote %dx%d in %dx%d\n",
3269                         env->out.enc_in.w, env->out.enc_in.h,
3270                         env->out.loc_src.w, env->out.loc_src.h,
3271                         env->out.loc_dpy.w, env->out.loc_src.h,
3272                         env->in.rem_dpy.w, env->in.rem_dpy.h,
3273                         env->in.dec_out.w, env->in.dec_out.h);
3274         } else if (!strcasecmp(var, "bitrate")) {
3275                 ast_cli(fd, "bitrate is [%d]\n", env->out.bitrate);
3276         } else if (!strcasecmp(var, "qmin")) {
3277                 ast_cli(fd, "qmin is [%d]\n", env->out.qmin);
3278         } else if (!strcasecmp(var, "fps")) {
3279                 ast_cli(fd, "fps is [%d]\n", env->out.fps);
3280         } else {
3281                 return 1;       /* unrecognised */
3282         }
3283         return 0;       /* recognised */
3284 }
3285
3286 /*! parse config command for video support. */
3287 int console_video_config(struct video_desc **penv,
3288         const char *var, const char *val)
3289 {
3290         struct video_desc *env;
3291
3292         if (penv == NULL) {
3293                 ast_log(LOG_WARNING, "bad argument penv=NULL\n");
3294                 return 1;       /* error */
3295         }
3296         /* allocate the video descriptor first time we get here */
3297         env = *penv;
3298         if (env == NULL) {
3299                 env = *penv = ast_calloc(1, sizeof(struct video_desc));
3300                 if (env == NULL) {
3301                         ast_log(LOG_WARNING, "fail to allocate video_desc\n");
3302                         return 1;       /* error */
3303                 
3304                 }
3305                 /* set default values */
3306                 ast_copy_string(env->out.videodevice, "X11", sizeof(env->out.videodevice));
3307                 env->out.fps = 5;
3308                 env->out.bitrate = 65000;
3309                 env->out.sendvideo = 1;
3310                 env->out.qmin = 3;
3311         }
3312         CV_START(var, val);
3313         CV_STR("videodevice", env->out.videodevice);
3314         CV_BOOL("sendvideo", env->out.sendvideo);
3315         CV_F("video_size", video_geom(&env->out.enc_in, val));
3316         CV_F("camera_size", video_geom(&env->out.loc_src, val));
3317         CV_F("local_size", video_geom(&env->out.loc_dpy, val));
3318         CV_F("remote_size", video_geom(&env->in.rem_dpy, val));
3319         CV_STR("keypad", env->keypad_file);
3320         CV_F("region", keypad_cfg_read(&env->gui, val));
3321         CV_STR("keypad_font", env->keypad_font);
3322         CV_STR("sdl_videodriver", env->sdl_videodriver);
3323         CV_UINT("fps", env->out.fps);
3324         CV_UINT("bitrate", env->out.bitrate);
3325         CV_UINT("qmin", env->out.qmin);
3326         CV_STR("videocodec", env->codec_name);
3327         return 1;       /* nothing found */
3328
3329         CV_END;         /* the 'nothing found' case */
3330         return 0;               /* found something */
3331 }
3332
3333 #endif  /* video support */