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