virtualize the interface for video grabbers, which should
[asterisk/asterisk.git] / channels / console_video.c
1 /*
2  * Experimental support for video sessions. We use SDL for rendering, ffmpeg
3  * as the codec library for encoding and decoding, and Video4Linux and X11
4  * to generate the local video stream.
5  *
6  * If one of these pieces is not available, either at compile time or at
7  * runtime, we do our best to run without it. Of course, no codec library
8  * means we can only deal with raw data, no SDL means we cannot do rendering,
9  * no V4L or X11 means we cannot generate data (but in principle we could
10  * stream from or record to a file).
11  *
12  * We need a recent (2007.07.12 or newer) version of ffmpeg to avoid warnings.
13  * Older versions might give 'deprecated' messages during compilation,
14  * thus not compiling in AST_DEVMODE, or don't have swscale, in which case
15  * you can try to compile #defining OLD_FFMPEG here.
16  *
17  * $Revision$
18  */
19
20 //#define DROP_PACKETS 5       /* if set, drop this % of video packets */
21 //#define OLD_FFMPEG    1       /* set for old ffmpeg with no swscale */
22
23 #include "asterisk.h"
24 #include <sys/ioctl.h>
25 #include "asterisk/cli.h"
26 #include "asterisk/file.h"
27 #include "asterisk/channel.h"
28
29 #include "console_video.h"
30
31 /*
32 The code is structured as follows.
33
34 When a new console channel is created, we call console_video_start()
35 to initialize SDL, the source, and the encoder/ decoder for the
36 formats in use (XXX the latter two should be done later, once the
37 codec negotiation is complete).  Also, a thread is created to handle
38 the video source and generate frames.
39
40 While communication is on, the local source is generated by the
41 video thread, which wakes up periodically, generates frames and
42 enqueues them in chan->readq.  Incoming rtp frames are passed to
43 console_write_video(), decoded and passed to SDL for display.
44
45 For as unfortunate and confusing as it can be, we need to deal with a
46 number of different video representations (size, codec/pixel format,
47 codec parameters), as follows:
48
49  loc_src        is the data coming from the camera/X11/etc.
50         The format is typically constrained by the video source.
51
52  enc_in         is the input required by the encoder.
53         Typically constrained in size by the encoder type.
54
55  enc_out        is the bitstream transmitted over RTP.
56         Typically negotiated while the call is established.
57
58  loc_dpy        is the format used to display the local video source.
59         Depending on user preferences this can have the same size as
60         loc_src_fmt, or enc_in_fmt, or thumbnail size (e.g. PiP output)
61
62  dec_in         is the incoming RTP bitstream. Negotiated
63         during call establishment, it is not necessarily the same as
64         enc_in_fmt
65
66  dec_out        the output of the decoder.
67         The format is whatever the other side sends, and the
68         buffer is allocated by avcodec_decode_... so we only
69         copy the data here.
70
71  rem_dpy        the format used to display the remote stream
72
73 We store the format info together with the buffer storing the data.
74 As a future optimization, a format/buffer may reference another one
75 if the formats are equivalent. This will save some unnecessary format
76 conversion.
77
78
79 In order to handle video you need to add to sip.conf (and presumably
80 iax.conf too) the following:
81
82         [general](+)
83                 videosupport=yes
84                 allow=h263      ; this or other video formats
85                 allow=h263p     ; this or other video formats
86
87  */
88
89 /*
90  * Codecs are absolutely necessary or we cannot do anything.
91  * SDL is optional (used for rendering only), so that we can still
92  * stream video withouth displaying it.
93  */
94 #if !defined(HAVE_VIDEO_CONSOLE) || !defined(HAVE_FFMPEG)
95 /* stubs if required pieces are missing */
96 int console_write_video(struct ast_channel *chan, struct ast_frame *f)
97 {
98         return 0;       /* writing video not supported */
99 }
100
101 int console_video_cli(struct video_desc *env, const char *var, int fd)
102 {
103         return 1;       /* nothing matched */
104 }
105
106 int console_video_config(struct video_desc **penv, const char *var, const char *val)
107 {
108         return 1;       /* no configuration */
109 }
110
111 void console_video_start(struct video_desc *env, struct ast_channel *owner)
112 {
113         ast_log(LOG_NOTICE, "voice only, console video support not present\n");
114 }
115
116 void console_video_uninit(struct video_desc *env)
117 {
118 }
119
120 int console_video_formats = 0;
121
122 #else /* defined(HAVE_FFMPEG) && defined(HAVE_SDL) */
123
124 /*! The list of video formats we support. */
125 int console_video_formats = 
126         AST_FORMAT_H263_PLUS | AST_FORMAT_H263 |
127         AST_FORMAT_MP4_VIDEO | AST_FORMAT_H264 | AST_FORMAT_H261 ;
128
129
130
131 static void my_scale(struct fbuf_t *in, AVPicture *p_in,
132         struct fbuf_t *out, AVPicture *p_out);
133
134 struct grab_desc;               /* grabber description */
135 struct video_codec_desc;        /* forward declaration */
136 /*
137  * Descriptor of the local source, made of the following pieces:
138  *  + configuration info (geometry, device name, fps...). These are read
139  *    from the config file and copied here before calling video_out_init();
140  *  + the frame buffer (buf) and source pixel format, allocated at init time;
141  *  + the encoding and RTP info, including timestamps to generate
142  *    frames at the correct rate;
143  *  + source-specific info, i.e. fd for /dev/video, dpy-image for x11, etc,
144  *    filled in by grabber_open
145  * NOTE: loc_src.data == NULL means the rest of the struct is invalid, and
146  *      the video source is not available.
147  */
148 struct video_out_desc {
149         /* video device support.
150          * videodevice and geometry are read from the config file.
151          * At the right time we try to open it and allocate a buffer.
152          * If we are successful, webcam_bufsize > 0 and we can read.
153          */
154         /* all the following is config file info copied from the parent */
155         char            videodevice[64];
156         int             fps;
157         int             bitrate;
158         int             qmin;
159
160         int sendvideo;
161
162         struct fbuf_t   loc_src_geometry;       /* local source geometry only (from config file) */
163         struct fbuf_t   enc_out;        /* encoder output buffer, allocated in video_out_init() */
164
165         struct video_codec_desc *enc;   /* encoder */
166         void            *enc_ctx;       /* encoding context */
167         AVCodec         *codec;
168         AVFrame         *enc_in_frame;  /* enc_in mapped into avcodec format. */
169                                         /* The initial part of AVFrame is an AVPicture */
170         int             mtu;
171         struct timeval  last_frame;     /* when we read the last frame ? */
172
173         struct grab_desc *grabber;
174         void            *grabber_data;
175 };
176
177 /*
178  * The overall descriptor, with room for config info, video source and
179  * received data descriptors, SDL info, etc.
180  * This should be globally visible to all modules (grabber, vcodecs, gui)
181  * and contain all configurtion info.
182  */
183 struct video_desc {
184         char                    codec_name[64]; /* the codec we use */
185
186         pthread_t               vthread;        /* video thread */
187         ast_mutex_t             dec_lock;       /* sync decoder and video thread */
188         int                     shutdown;       /* set to shutdown vthread */
189         struct ast_channel      *owner;         /* owner channel */
190
191
192         struct fbuf_t   enc_in;         /* encoder input buffer, allocated in video_out_init() */
193
194         char                    keypad_file[256];       /* image for the keypad */
195         char                    keypad_font[256];       /* font for the keypad */
196
197         char                    sdl_videodriver[256];
198
199         struct fbuf_t           rem_dpy;        /* display remote video, no buffer (it is in win[WIN_REMOTE].bmp) */
200         struct fbuf_t           loc_dpy;        /* display local source, no buffer (managed by SDL in bmp[1]) */
201
202
203         /* local information for grabbers, codecs, gui */
204         struct gui_info         *gui;
205         struct video_dec_desc   *in;            /* remote video descriptor */
206         struct video_out_desc   out;            /* local video descriptor */
207 };
208
209 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p);
210
211 static void fbuf_free(struct fbuf_t *b)
212 {
213         struct fbuf_t x = *b;
214
215         if (b->data && b->size)
216                 ast_free(b->data);
217         bzero(b, sizeof(*b));
218         /* restore some fields */
219         b->w = x.w;
220         b->h = x.h;
221         b->pix_fmt = x.pix_fmt;
222 }
223
224 #include "vcodecs.c"
225 #include "console_gui.c"
226
227 /*------ end codec specific code -----*/
228
229 /* descriptor for a grabber */
230 struct grab_desc {
231         const char *name;
232         void *(*open)(const char *name, struct fbuf_t *geom, int fps);
233         struct fbuf_t *(*read)(void *d);
234         void (*move)(void *d, int dx, int dy);
235         void *(*close)(void *d);
236 };
237
238
239 #ifdef HAVE_X11
240 struct grab_x11_desc {
241         Display         *dpy;                   /* x11 grabber info */
242         XImage          *image;
243         int             screen_width;   /* width of X screen */
244         int             screen_height;  /* height of X screen */
245         struct fbuf_t   b;
246 };
247
248 static void *grab_x11_open(const char *name, struct fbuf_t *geom, int fps)
249 {
250         XImage *im;
251         int screen_num;
252         struct grab_x11_desc *v;
253         struct fbuf_t *b;
254
255         if (strcasecmp(name, "X11"))
256                 return NULL;    /* not us */
257         v = ast_calloc(1, sizeof(*v));
258         if (v == NULL)
259                 return NULL;    /* no memory */
260
261         /* init the connection with the X server */
262         v->dpy = XOpenDisplay(NULL);
263         if (v->dpy == NULL) {
264                 ast_log(LOG_WARNING, "error opening display\n");
265                 goto error;
266         }
267
268         v->b = *geom;   /* copy geometry */
269         b = &v->b;      /* shorthand */
270         /* find width and height of the screen */
271         screen_num = DefaultScreen(v->dpy);
272         v->screen_width = DisplayWidth(v->dpy, screen_num);
273         v->screen_height = DisplayHeight(v->dpy, screen_num);
274
275         v->image = im = XGetImage(v->dpy,
276                 RootWindow(v->dpy, DefaultScreen(v->dpy)),
277                 b->x, b->y, b->w, b->h, AllPlanes, ZPixmap);
278         if (v->image == NULL) {
279                 ast_log(LOG_WARNING, "error creating Ximage\n");
280                 goto error;
281         }
282         switch (im->bits_per_pixel) {
283         case 32:
284                 b->pix_fmt = PIX_FMT_RGBA32;
285                 break;
286         case 16:
287                 b->pix_fmt = (im->green_mask == 0x7e0) ? PIX_FMT_RGB565 : PIX_FMT_RGB555;
288                 break;
289         }
290
291         ast_log(LOG_NOTICE, "image: data %p %d bpp fmt %d, mask 0x%lx 0x%lx 0x%lx\n",
292                 im->data,
293                 im->bits_per_pixel,
294                 b->pix_fmt,
295                 im->red_mask, im->green_mask, im->blue_mask);
296
297         /* set the pointer but not the size as this is not malloc'ed */
298         b->data = (uint8_t *)im->data;
299         return v;
300
301 error:
302         /* XXX maybe XDestroy (v->image) ? */
303         if (v->dpy)
304                 XCloseDisplay(v->dpy);
305         v->dpy = NULL;
306         ast_free(v);
307         return NULL;
308 }
309
310 static struct fbuf_t *grab_x11_read(void *desc)
311 {
312         /* read frame from X11 */
313         struct grab_x11_desc *v = desc;
314         struct fbuf_t *b = &v->b;
315
316         XGetSubImage(v->dpy,
317                 RootWindow(v->dpy, DefaultScreen(v->dpy)),
318                         b->x, b->y, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);
319
320                 b->data = (uint8_t *)v->image->data;
321         return b;
322 }
323
324 static int boundary_checks(int x, int limit)
325 {
326         return (x <= 0) ? 0 : (x > limit ? limit : x);
327 }
328
329 /* move the origin for the grabbed area */
330 static void grab_x11_move(void *desc, int dx, int dy)
331 {
332         struct grab_x11_desc *v = desc;
333
334         v->b.x = boundary_checks(v->b.x + dx, v->screen_width - v->b.w);
335         v->b.y = boundary_checks(v->b.y + dy, v->screen_height - v->b.h);
336 }
337
338 static void *grab_x11_close(void *desc)
339 {
340         struct grab_x11_desc *v = desc;
341
342         XCloseDisplay(v->dpy);
343         v->dpy = NULL;
344         v->image = NULL;
345         ast_free(v);
346         return NULL;
347 }
348
349 static struct grab_desc grab_x11_desc = {
350         .name = "X11",
351         .open = grab_x11_open,
352         .read = grab_x11_read,
353         .move = grab_x11_move,
354         .close = grab_x11_close,
355 };
356
357 #endif  /* HAVE_X11 */
358
359 /* Video4Linux stuff is only used in grabber_open() */
360 #ifdef HAVE_VIDEODEV_H
361 #include <linux/videodev.h>
362
363 struct grab_v4l1_desc {
364         int fd;
365         int fps;
366         struct fbuf_t   b;
367 };
368
369 /*!
370  * Open the local video source and allocate a buffer
371  * for storing the image. Return 0 on success, -1 on error
372  */
373 static void *grab_v4l1_open(const char *dev, struct fbuf_t *geom, int fps)
374 {
375         struct video_window vw = { 0 }; /* camera attributes */
376         struct video_picture vp;
377         int fd, i;
378         struct grab_v4l1_desc *v;
379         struct fbuf_t *b;
380
381         fd = open(dev, O_RDONLY | O_NONBLOCK);
382         if (fd < 0) {
383                 ast_log(LOG_WARNING, "error opening camera %s\n", dev);
384                 return NULL;
385         }
386
387         v = ast_calloc(1, sizeof(*v));
388         if (v == NULL) {
389                 ast_log(LOG_WARNING, "no memory for camera %s\n", dev);
390                 close(fd);
391                 return NULL;    /* no memory */
392         }
393         v->fd = fd;
394         v->b = *geom;
395         b = &v->b;      /* shorthand */
396
397         i = fcntl(fd, F_GETFL);
398         if (-1 == fcntl(fd, F_SETFL, i | O_NONBLOCK)) {
399                 /* non fatal, just emit a warning */
400                 ast_log(LOG_WARNING, "error F_SETFL for %s [%s]\n",
401                         dev, strerror(errno));
402         }
403         /* set format for the camera.
404          * In principle we could retry with a different format if the
405          * one we are asking for is not supported.
406          */
407         vw.width = b->w;
408         vw.height = b->h;
409         vw.flags = fps << 16;
410         if (ioctl(fd, VIDIOCSWIN, &vw) == -1) {
411                 ast_log(LOG_WARNING, "error setting format for %s [%s]\n",
412                         dev, strerror(errno));
413                 goto error;
414         }
415         if (ioctl(fd, VIDIOCGPICT, &vp) == -1) {
416                 ast_log(LOG_WARNING, "error reading picture info\n");
417                 goto error;
418         }
419         ast_log(LOG_WARNING,
420                 "contrast %d bright %d colour %d hue %d white %d palette %d\n",
421                 vp.contrast, vp.brightness,
422                 vp.colour, vp.hue,
423                 vp.whiteness, vp.palette);
424         /* set the video format. Here again, we don't necessary have to
425          * fail if the required format is not supported, but try to use
426          * what the camera gives us.
427          */
428         b->pix_fmt = vp.palette;
429         vp.palette = VIDEO_PALETTE_YUV420P;
430         if (ioctl(v->fd, VIDIOCSPICT, &vp) == -1) {
431                 ast_log(LOG_WARNING, "error setting palette, using %d\n",
432                         b->pix_fmt);
433         } else
434                 b->pix_fmt = vp.palette;
435         /* allocate the source buffer.
436          * XXX, the code here only handles yuv411, for other formats
437          * we need to look at pix_fmt and set size accordingly
438          */
439         b->size = (b->w * b->h * 3)/2;  /* yuv411 */
440         ast_log(LOG_WARNING, "videodev %s opened, size %dx%d %d\n",
441                 dev, b->w, b->h, b->size);
442         b->data = ast_calloc(1, b->size);
443         if (!b->data) {
444                 ast_log(LOG_WARNING, "error allocating buffer %d bytes\n",
445                         b->size);
446                 goto error;
447         }
448         ast_log(LOG_WARNING, "success opening camera\n");
449         return v;
450
451 error:
452         close(v->fd);
453         fbuf_free(b);
454         ast_free(v);
455         return NULL;
456 }
457
458 static struct fbuf_t *grab_v4l1_read(void *desc)
459 {
460         struct grab_v4l1_desc *v = desc;
461         struct fbuf_t *b = &v->b;
462         for (;;) {
463                 int r, l = b->size - b->used;
464                 r = read(v->fd, b->data + b->used, l);
465                 // ast_log(LOG_WARNING, "read %d of %d bytes from webcam\n", r, l);
466                 if (r < 0)      /* read error */
467                         break;
468                 if (r == 0)     /* no data */
469                         break;
470                 b->used += r;
471                 if (r == l) {
472                         b->used = 0; /* prepare for next frame */
473                         return b;
474                 }
475         }
476         return NULL;
477 }
478
479 static void *grab_v4l1_close(void *desc)
480 {
481         struct grab_v4l1_desc *v = desc;
482
483         close(v->fd);
484         v->fd = -1;
485         fbuf_free(&v->b);
486         ast_free(v);
487         return NULL;
488 }
489
490 static struct grab_desc grab_v4l1_desc = {
491         .name = "v4l1",
492         .open = grab_v4l1_open,
493         .read = grab_v4l1_read,
494         .close = grab_v4l1_close,
495 };
496 #endif /* HAVE_VIDEODEV_H */
497
498 static struct grab_desc *my_grabbers[] = {
499         &grab_x11_desc,
500         &grab_v4l1_desc,
501         NULL
502 };
503
504 /* try to open a video source, return 0 on success, 1 on error
505  */
506 static int grabber_open(struct video_out_desc *v)
507 {
508         struct grab_desc *g;
509         void *g_data;
510         int i;
511
512         for (i = 0; (g = my_grabbers[i]); i++) {
513                 g_data = g->open(v->videodevice, &v->loc_src_geometry, v->fps);
514                 if (g_data) {
515                         v->grabber = g;
516                         v->grabber_data = g_data;
517                         return 0;
518                 }
519         }
520         return 1; /* no source found */
521 }
522
523 /*! \brief complete a buffer from the local video source.
524  * Called by get_video_frames(), in turn called by the video thread.
525  */
526 static struct fbuf_t *grabber_read(struct video_out_desc *v)
527 {
528         struct timeval now = ast_tvnow();
529
530         if (v->grabber == NULL) /* not initialized */
531                 return 0;
532
533         /* check if it is time to read */
534         if (ast_tvzero(v->last_frame))
535                 v->last_frame = now;
536         if (ast_tvdiff_ms(now, v->last_frame) < 1000/v->fps)
537                 return 0;       /* too early */
538         v->last_frame = now; /* XXX actually, should correct for drift */
539         return v->grabber->read(v->grabber_data);
540 }
541
542 static void grabber_move(struct video_out_desc *v, int dx, int dy)
543 {
544         if (v->grabber && v->grabber->move)
545                 v->grabber->move(v->grabber_data, dx, dy);
546 }
547
548 /* Helper function to process incoming video.
549  * For each incoming video call invoke ffmpeg_init() to intialize
550  * the decoding structure then incoming video frames are processed
551  * by write_video() which in turn calls pre_process_data(), to extract
552  * the bitstream; accumulates data into a buffer within video_desc. When
553  * a frame is complete (determined by the marker bit in the RTP header)
554  * call decode_video() to decoding and if it successful call show_frame()
555  * to display the frame.
556  */
557
558 /*
559  * Map the codec name to the library. If not recognised, use a default.
560  * This is useful in the output path where we decide by name, presumably.
561  */
562 static struct video_codec_desc *map_config_video_format(char *name)
563 {
564         int i;
565
566         for (i = 0; supported_codecs[i]; i++)
567                 if (!strcasecmp(name, supported_codecs[i]->name))
568                         break;
569         if (supported_codecs[i] == NULL) {
570                 ast_log(LOG_WARNING, "Cannot find codec for '%s'\n", name);
571                 i = 0;
572                 strcpy(name, supported_codecs[i]->name);
573         }
574         ast_log(LOG_WARNING, "Using codec '%s'\n", name);
575         return supported_codecs[i];
576 }
577
578
579 /*! \brief uninitialize the descriptor for local video stream */
580 static int video_out_uninit(struct video_desc *env)
581 {
582         struct video_out_desc *v = &env->out;
583
584         /* XXX this should be a codec callback */
585         if (v->enc_ctx) {
586                 AVCodecContext *enc_ctx = (AVCodecContext *)v->enc_ctx;
587                 avcodec_close(enc_ctx);
588                 av_free(enc_ctx);
589                 v->enc_ctx = NULL;
590         }
591         if (v->enc_in_frame) {
592                 av_free(v->enc_in_frame);
593                 v->enc_in_frame = NULL;
594         }
595         v->codec = NULL;        /* nothing to free, this is only a reference */
596         /* release the buffers */
597         fbuf_free(&env->enc_in);
598         fbuf_free(&v->enc_out);
599         /* close the grabber */
600         sleep(1);
601         if (v->grabber) {
602                 v->grabber_data = v->grabber->close(v->grabber_data);
603                 v->grabber = NULL;
604         }
605         return -1;
606 }
607
608 /*
609  * Initialize the encoder for the local source:
610  * - AVCodecContext, AVCodec, AVFrame are used by ffmpeg for encoding;
611  * - encbuf is used to store the encoded frame (to be sent)
612  * - mtu is used to determine the max size of video fragment
613  * NOTE: we enter here with the video source already open.
614  */
615 static int video_out_init(struct video_desc *env)
616 {
617         int codec;
618         int size;
619         struct fbuf_t *enc_in;
620         struct video_out_desc *v = &env->out;
621
622         v->enc_ctx              = NULL;
623         v->codec                = NULL;
624         v->enc_in_frame         = NULL;
625         v->enc_out.data         = NULL;
626
627         codec = map_video_format(v->enc->format, CM_WR);
628         v->codec = avcodec_find_encoder(codec);
629         if (!v->codec) {
630                 ast_log(LOG_WARNING, "Cannot find the encoder for format %d\n",
631                         codec);
632                 return -1;      /* error, but nothing to undo yet */
633         }
634
635         v->mtu = 1400;  /* set it early so the encoder can use it */
636
637         /* allocate the input buffer for encoding.
638          * ffmpeg only supports PIX_FMT_YUV420P for the encoding.
639          */
640         enc_in = &env->enc_in;
641         enc_in->pix_fmt = PIX_FMT_YUV420P;
642         enc_in->size = (enc_in->w * enc_in->h * 3)/2;
643         enc_in->data = ast_calloc(1, enc_in->size);
644         if (!enc_in->data) {
645                 ast_log(LOG_WARNING, "Cannot allocate encoder input buffer\n");
646                 return video_out_uninit(env);
647         }
648         /* construct an AVFrame that points into buf_in */
649         v->enc_in_frame = avcodec_alloc_frame();
650         if (!v->enc_in_frame) {
651                 ast_log(LOG_WARNING, "Unable to allocate the encoding video frame\n");
652                 return video_out_uninit(env);
653         }
654
655         /* parameters for PIX_FMT_YUV420P */
656         size = enc_in->w * enc_in->h;
657         v->enc_in_frame->data[0] = enc_in->data;
658         v->enc_in_frame->data[1] = v->enc_in_frame->data[0] + size;
659         v->enc_in_frame->data[2] = v->enc_in_frame->data[1] + size/4;
660         v->enc_in_frame->linesize[0] = enc_in->w;
661         v->enc_in_frame->linesize[1] = enc_in->w/2;
662         v->enc_in_frame->linesize[2] = enc_in->w/2;
663
664         /* now setup the parameters for the encoder.
665          * XXX should be codec-specific
666          */
667     {
668         AVCodecContext *enc_ctx = avcodec_alloc_context();
669         v->enc_ctx = enc_ctx;
670         enc_ctx->pix_fmt = enc_in->pix_fmt;
671         enc_ctx->width = enc_in->w;
672         enc_ctx->height = enc_in->h;
673         /* XXX rtp_callback ?
674          * rtp_mode so ffmpeg inserts as many start codes as possible.
675          */
676         enc_ctx->rtp_mode = 1;
677         enc_ctx->rtp_payload_size = v->mtu / 2; // mtu/2
678         enc_ctx->bit_rate = v->bitrate;
679         enc_ctx->bit_rate_tolerance = enc_ctx->bit_rate/2;
680         enc_ctx->qmin = v->qmin;        /* should be configured */
681         enc_ctx->time_base = (AVRational){1, v->fps};
682         enc_ctx->gop_size = v->fps*5; // emit I frame every 5 seconds
683
684         v->enc->enc_init(v->enc_ctx);
685  
686         if (avcodec_open(enc_ctx, v->codec) < 0) {
687                 ast_log(LOG_WARNING, "Unable to initialize the encoder %d\n",
688                         codec);
689                 av_free(enc_ctx);
690                 v->enc_ctx = NULL;
691                 return video_out_uninit(env);
692         }
693     }
694         /*
695          * Allocate enough for the encoded bitstream. As we are compressing,
696          * we hope that the output is never larger than the input size.
697          */
698         v->enc_out.data = ast_calloc(1, enc_in->size);
699         v->enc_out.size = enc_in->size;
700         v->enc_out.used = 0;
701
702         return 0;
703 }
704
705 /*! \brief uninitialize the entire environment.
706  * In practice, signal the thread and give it a bit of time to
707  * complete, giving up if it gets stuck. Because uninit
708  * is called from hangup with the channel locked, and the thread
709  * uses the chan lock, we need to unlock here. This is unsafe,
710  * and we should really use refcounts for the channels.
711  */
712 void console_video_uninit(struct video_desc *env)
713 {
714         int i, t = 100; /* initial wait is shorter, than make it longer */
715         env->shutdown = 1;
716         for (i=0; env->shutdown && i < 10; i++) {
717                 ast_channel_unlock(env->owner);
718                 usleep(t);
719                 t = 1000000;
720                 ast_channel_lock(env->owner);
721         }
722         env->owner = NULL;
723 }
724
725 /*! fill an AVPicture from our fbuf info, as it is required by
726  * the image conversion routines in ffmpeg.
727  * XXX This depends on the format.
728  */
729 static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p)
730 {
731         /* provide defaults for commonly used formats */
732         int l4 = b->w * b->h/4; /* size of U or V frame */
733         int len = b->w;         /* Y linesize, bytes */
734         int luv = b->w/2;       /* U/V linesize, bytes */
735
736         bzero(p, sizeof(*p));
737         switch (b->pix_fmt) {
738         case PIX_FMT_RGB555:
739         case PIX_FMT_RGB565:
740                 len *= 2;
741                 luv = 0;
742                 break;
743         case PIX_FMT_RGBA32:
744                 len *= 4;
745                 luv = 0;
746                 break;
747         case PIX_FMT_YUYV422:   /* Packed YUV 4:2:2, 16bpp, Y0 Cb Y1 Cr */
748                 len *= 2;       /* all data in first plane, probably */
749                 luv = 0;
750                 break;
751         }
752         p->data[0] = b->data;
753         p->linesize[0] = len;
754         /* these are only valid for component images */
755         p->data[1] = luv ? b->data + 4*l4 : b->data+len;
756         p->data[2] = luv ? b->data + 5*l4 : b->data+len;
757         p->linesize[1] = luv;
758         p->linesize[2] = luv;
759         return p;
760 }
761
762 /*! convert/scale between an input and an output format.
763  * Old version of ffmpeg only have img_convert, which does not rescale.
764  * New versions use sws_scale which does both.
765  */
766 static void my_scale(struct fbuf_t *in, AVPicture *p_in,
767         struct fbuf_t *out, AVPicture *p_out)
768 {
769         AVPicture my_p_in, my_p_out;
770
771         if (p_in == NULL)
772                 p_in = fill_pict(in, &my_p_in);
773         if (p_out == NULL)
774                 p_out = fill_pict(out, &my_p_out);
775
776 #ifdef OLD_FFMPEG
777         /* XXX img_convert is deprecated, and does not do rescaling */
778         img_convert(p_out, out->pix_fmt,
779                 p_in, in->pix_fmt, in->w, in->h);
780 #else /* XXX replacement */
781     {
782         struct SwsContext *convert_ctx;
783
784         convert_ctx = sws_getContext(in->w, in->h, in->pix_fmt,
785                 out->w, out->h, out->pix_fmt,
786                 SWS_BICUBIC, NULL, NULL, NULL);
787         if (convert_ctx == NULL) {
788                 ast_log(LOG_ERROR, "FFMPEG::convert_cmodel : swscale context initialization failed");
789                 return;
790         }
791         if (0)
792                 ast_log(LOG_WARNING, "in %d %dx%d out %d %dx%d\n",
793                         in->pix_fmt, in->w, in->h, out->pix_fmt, out->w, out->h);
794         sws_scale(convert_ctx,
795                 p_in->data, p_in->linesize,
796                 in->w, in->h, /* src slice */
797                 p_out->data, p_out->linesize);
798
799         sws_freeContext(convert_ctx);
800     }
801 #endif /* XXX replacement */
802 }
803
804 struct video_desc *get_video_desc(struct ast_channel *c);
805
806 /*
807  * This function is called (by asterisk) for each video packet
808  * coming from the network (the 'in' path) that needs to be processed.
809  * We need to reconstruct the entire video frame before we can decode it.
810  * After a video packet is received we have to:
811  * - extract the bitstream with pre_process_data()
812  * - append the bitstream to a buffer
813  * - if the fragment is the last (RTP Marker) we decode it with decode_video()
814  * - after the decoding is completed we display the decoded frame with show_frame()
815  */
816 int console_write_video(struct ast_channel *chan, struct ast_frame *f);
817 int console_write_video(struct ast_channel *chan, struct ast_frame *f)
818 {
819         struct video_desc *env = get_video_desc(chan);
820         struct video_dec_desc *v = env->in;
821
822         if (!env->gui)  /* no gui, no rendering */
823                 return 0;
824         if (v == NULL)
825                 env->in = v = dec_init(f->subclass & ~1);
826         if (v == NULL) {
827                 /* This is not fatal, but we won't have incoming video */
828                 ast_log(LOG_WARNING, "Cannot initialize input decoder\n");
829                 return 0;
830         }
831
832         if (v->dec_in_cur == NULL)      /* no buffer for incoming frames, drop */
833                 return 0;
834 #if defined(DROP_PACKETS) && DROP_PACKETS > 0
835         /* Simulate lost packets */
836         if ((random() % 10000) <= 100*DROP_PACKETS) {
837                 ast_log(LOG_NOTICE, "Packet lost [%d]\n", f->seqno);
838                 return 0;
839         }
840 #endif
841         if (v->discard) {
842                 /*
843                  * In discard mode, drop packets until we find one with
844                  * the RTP marker set (which is the end of frame).
845                  * Note that the RTP marker flag is sent as the LSB of the
846                  * subclass, which is a  bitmask of formats. The low bit is
847                  * normally used for audio so there is no interference.
848                  */
849                 if (f->subclass & 0x01) {
850                         v->dec_in_cur->used = 0;
851                         v->dec_in_cur->ebit = 0;
852                         v->next_seq = f->seqno + 1;     /* wrap at 16 bit */
853                         v->discard = 0;
854                         ast_log(LOG_WARNING, "out of discard mode, frame %d\n", f->seqno);
855                 }
856                 return 0;
857         }
858
859         /*
860          * Only in-order fragments will be accepted. Remember seqno
861          * has 16 bit so there is wraparound. Also, ideally we could
862          * accept a bit of reordering, but at the moment we don't.
863          */
864         if (v->next_seq != f->seqno) {
865                 ast_log(LOG_WARNING, "discarding frame out of order, %d %d\n",
866                         v->next_seq, f->seqno);
867                 v->discard = 1;
868                 return 0;
869         }
870         v->next_seq++;
871
872         if (f->data == NULL || f->datalen < 2) {
873                 ast_log(LOG_WARNING, "empty video frame, discard\n");
874                 return 0;
875         }
876         if (v->d_callbacks->dec_decap(v->dec_in_cur, f->data, f->datalen)) {
877                 ast_log(LOG_WARNING, "error in dec_decap, enter discard\n");
878                 v->discard = 1;
879         }
880         if (f->subclass & 0x01) {       // RTP Marker
881                 /* prepare to decode: advance the buffer so the video thread knows. */
882                 struct fbuf_t *tmp = v->dec_in_cur;     /* store current pointer */
883                 ast_mutex_lock(&env->dec_lock);
884                 if (++v->dec_in_cur == &v->dec_in[N_DEC_IN])    /* advance to next, circular */
885                         v->dec_in_cur = &v->dec_in[0];
886                 if (v->dec_in_dpy == NULL) {    /* were not displaying anything, so set it */
887                         v->dec_in_dpy = tmp;
888                 } else if (v->dec_in_dpy == v->dec_in_cur) { /* current slot is busy */
889                         v->dec_in_cur = NULL;
890                 }
891                 ast_mutex_unlock(&env->dec_lock);
892         }
893         return 0;
894 }
895
896
897 /*! \brief read a frame from webcam or X11 through grabber_read(),
898  * display it,  then encode and split it.
899  * Return a list of ast_frame representing the video fragments.
900  * The head pointer is returned by the function, the tail pointer
901  * is returned as an argument.
902  */
903 static struct ast_frame *get_video_frames(struct video_desc *env, struct ast_frame **tail)
904 {
905         struct video_out_desc *v = &env->out;
906         struct ast_frame *dummy;
907         struct fbuf_t *loc_src = grabber_read(v);
908
909         if (!loc_src)
910                 return NULL;    /* can happen, e.g. we are reading too early */
911
912         if (tail == NULL)
913                 tail = &dummy;
914         *tail = NULL;
915         /* Scale the video for the encoder, then use it for local rendering
916          * so we will see the same as the remote party.
917          */
918         my_scale(loc_src, NULL, &env->enc_in, NULL);
919         show_frame(env, WIN_LOCAL);
920         if (!v->sendvideo)
921                 return NULL;
922         if (v->enc_out.data == NULL) {
923                 static volatile int a = 0;
924                 if (a++ < 2)
925                         ast_log(LOG_WARNING, "fail, no encbuf\n");
926                 return NULL;
927         }
928         v->enc->enc_run(v);
929         return v->enc->enc_encap(&v->enc_out, v->mtu, tail);
930 }
931
932 /*
933  * Helper thread to periodically poll the video source and enqueue the
934  * generated frames to the channel's queue.
935  * Using a separate thread also helps because the encoding can be
936  * computationally expensive so we don't want to starve the main thread.
937  */
938 static void *video_thread(void *arg)
939 {
940         struct video_desc *env = arg;
941         int count = 0;
942         char save_display[128] = "";
943
944         /* if sdl_videodriver is set, override the environment. Also,
945          * if it contains 'console' override DISPLAY around the call to SDL_Init
946          * so we use the console as opposed to the x11 version of aalib
947          */
948         if (!ast_strlen_zero(env->sdl_videodriver)) { /* override */
949                 const char *s = getenv("DISPLAY");
950                 setenv("SDL_VIDEODRIVER", env->sdl_videodriver, 1);
951                 if (s && !strcasecmp(env->sdl_videodriver, "aalib-console")) {
952                         ast_copy_string(save_display, s, sizeof(save_display));
953                         unsetenv("DISPLAY");
954                 }
955         }
956         sdl_setup(env);
957         if (!ast_strlen_zero(save_display))
958                 setenv("DISPLAY", save_display, 1);
959
960         /* initialize grab coordinates */
961         env->out.loc_src_geometry.x = 0;
962         env->out.loc_src_geometry.y = 0;
963
964         ast_mutex_init(&env->dec_lock); /* used to sync decoder and renderer */
965
966         if (grabber_open(&env->out)) {
967                 ast_log(LOG_WARNING, "cannot open local video source\n");
968         } else {
969 #if 0
970                 /* In principle, try to register the fd.
971                  * In practice, many webcam drivers do not support select/poll,
972                  * so don't bother and instead read periodically from the
973                  * video thread.
974                  */
975                 if (env->out.fd >= 0)
976                         ast_channel_set_fd(env->owner, 1, env->out.fd);
977 #endif
978                 video_out_init(env);
979         }
980
981         for (;;) {
982                 struct timeval t = { 0, 50000 };        /* XXX 20 times/sec */
983                 struct ast_frame *p, *f;
984                 struct ast_channel *chan = env->owner;
985                 int fd = chan->alertpipe[1];
986                 char *caption = NULL, buf[160];
987
988                 /* determine if video format changed */
989                 if (count++ % 10 == 0) {
990                         if (env->out.sendvideo)
991                             sprintf(buf, "%s %s %dx%d @@ %dfps %dkbps",
992                                 env->out.videodevice, env->codec_name,
993                                 env->enc_in.w, env->enc_in.h,
994                                 env->out.fps, env->out.bitrate/1000);
995                         else
996                             sprintf(buf, "hold");
997                         caption = buf;
998                 }
999
1000                 /* manage keypad events */
1001                 /* XXX here we should always check for events,
1002                 * otherwise the drag will not work */ 
1003                 if (env->gui)
1004                         eventhandler(env, caption);
1005  
1006                 /* sleep for a while */
1007                 ast_select(0, NULL, NULL, NULL, &t);
1008
1009             if (env->in) {
1010                 struct video_dec_desc *v = env->in;
1011                 
1012                 /*
1013                  * While there is something to display, call the decoder and free
1014                  * the buffer, possibly enabling the receiver to store new data.
1015                  */
1016                 while (v->dec_in_dpy) {
1017                         struct fbuf_t *tmp = v->dec_in_dpy;     /* store current pointer */
1018
1019                         if (v->d_callbacks->dec_run(v, tmp))
1020                                 show_frame(env, WIN_REMOTE);
1021                         tmp->used = 0;  /* mark buffer as free */
1022                         tmp->ebit = 0;
1023                         ast_mutex_lock(&env->dec_lock);
1024                         if (++v->dec_in_dpy == &v->dec_in[N_DEC_IN])    /* advance to next, circular */
1025                                 v->dec_in_dpy = &v->dec_in[0];
1026
1027                         if (v->dec_in_cur == NULL)      /* receiver was idle, enable it... */
1028                                 v->dec_in_cur = tmp;    /* using the slot just freed */
1029                         else if (v->dec_in_dpy == v->dec_in_cur) /* this was the last slot */
1030                                 v->dec_in_dpy = NULL;   /* nothing more to display */
1031                         ast_mutex_unlock(&env->dec_lock);
1032                 }
1033             }
1034
1035                 if (env->shutdown)
1036                         break;
1037                 f = get_video_frames(env, &p);  /* read and display */
1038                 if (!f)
1039                         continue;
1040                 chan = env->owner;
1041                 ast_channel_lock(chan);
1042
1043                 /* AST_LIST_INSERT_TAIL is only good for one frame, cannot use here */
1044                 if (chan->readq.first == NULL) {
1045                         chan->readq.first = f;
1046                 } else {
1047                         chan->readq.last->frame_list.next = f;
1048                 }
1049                 chan->readq.last = p;
1050                 /*
1051                  * more or less same as ast_queue_frame, but extra
1052                  * write on the alertpipe to signal frames.
1053                  */
1054                 if (fd > -1) {
1055                         int blah = 1, l = sizeof(blah);
1056                         for (p = f; p; p = AST_LIST_NEXT(p, frame_list)) {
1057                                 if (write(fd, &blah, l) != l)
1058                                         ast_log(LOG_WARNING, "Unable to write to alert pipe on %s, frametype/subclass %d/%d: %s!\n",
1059                                             chan->name, f->frametype, f->subclass, strerror(errno));
1060                         }
1061                 }
1062                 ast_channel_unlock(chan);
1063         }
1064         /* thread terminating, here could call the uninit */
1065         /* uninitialize the local and remote video environments */
1066         env->in = dec_uninit(env->in);
1067         video_out_uninit(env);
1068
1069         if (env->gui)
1070                 env->gui = cleanup_sdl(env->gui);
1071         ast_mutex_destroy(&env->dec_lock);
1072         env->shutdown = 0;
1073         return NULL;
1074 }
1075
1076 static void copy_geometry(struct fbuf_t *src, struct fbuf_t *dst)
1077 {
1078         if (dst->w == 0)
1079                 dst->w = src->w;
1080         if (dst->h == 0)
1081                 dst->h = src->h;
1082 }
1083
1084 /*! initialize the video environment.
1085  * Apart from the formats (constant) used by sdl and the codec,
1086  * we use enc_in as the basic geometry.
1087  */
1088 static void init_env(struct video_desc *env)
1089 {
1090         struct fbuf_t *c = &(env->out.loc_src_geometry);                /* local source */
1091         struct fbuf_t *ei = &(env->enc_in);             /* encoder input */
1092         struct fbuf_t *ld = &(env->loc_dpy);    /* local display */
1093         struct fbuf_t *rd = &(env->rem_dpy);            /* remote display */
1094
1095         c->pix_fmt = PIX_FMT_YUV420P;   /* default - camera format */
1096         ei->pix_fmt = PIX_FMT_YUV420P;  /* encoder input */
1097         if (ei->w == 0 || ei->h == 0) {
1098                 ei->w = 352;
1099                 ei->h = 288;
1100         }
1101         ld->pix_fmt = rd->pix_fmt = PIX_FMT_YUV420P; /* sdl format */
1102         /* inherit defaults */
1103         copy_geometry(ei, c);   /* camera inherits from encoder input */
1104         copy_geometry(ei, rd);  /* remote display inherits from encoder input */
1105         copy_geometry(rd, ld);  /* local display inherits from remote display */
1106 }
1107
1108 /*!
1109  * The first call to the video code, called by oss_new() or similar.
1110  * Here we initialize the various components we use, namely SDL for display,
1111  * ffmpeg for encoding/decoding, and a local video source.
1112  * We do our best to progress even if some of the components are not
1113  * available.
1114  */
1115 void console_video_start(struct video_desc *env, struct ast_channel *owner)
1116 {
1117         if (env == NULL)        /* video not initialized */
1118                 return;
1119         if (owner == NULL)      /* nothing to do if we don't have a channel */
1120                 return;
1121         env->owner = owner;
1122         init_env(env);
1123         env->out.enc = map_config_video_format(env->codec_name);
1124
1125         ast_log(LOG_WARNING, "start video out %s %dx%d\n",
1126                 env->codec_name, env->enc_in.w,  env->enc_in.h);
1127         /*
1128          * Register all codecs supported by the ffmpeg library.
1129          * We only need to do it once, but probably doesn't
1130          * harm to do it multiple times.
1131          */
1132         avcodec_init();
1133         avcodec_register_all();
1134         av_log_set_level(AV_LOG_ERROR); /* only report errors */
1135
1136         if (env->out.fps == 0) {
1137                 env->out.fps = 15;
1138                 ast_log(LOG_WARNING, "fps unset, forcing to %d\n", env->out.fps);
1139         }
1140         if (env->out.bitrate == 0) {
1141                 env->out.bitrate = 65000;
1142                 ast_log(LOG_WARNING, "bitrate unset, forcing to %d\n", env->out.bitrate);
1143         }
1144
1145         ast_pthread_create_background(&env->vthread, NULL, video_thread, env);
1146 }
1147
1148 /*
1149  * Parse a geometry string, accepting also common names for the formats.
1150  * Trick: if we have a leading > or < and a numeric geometry,
1151  * return the larger or smaller one.
1152  * E.g. <352x288 gives the smaller one, 320x240
1153  */
1154 static int video_geom(struct fbuf_t *b, const char *s)
1155 {
1156         int w = 0, h = 0;
1157
1158         static struct {
1159                 const char *s; int w; int h;
1160         } *fp, formats[] = {
1161                 {"16cif",       1408, 1152 },
1162                 {"xga",         1024, 768 },
1163                 {"4cif",        704, 576 },
1164                 {"vga",         640, 480 },
1165                 {"cif",         352, 288 },
1166                 {"qvga",        320, 240 },
1167                 {"qcif",        176, 144 },
1168                 {"sqcif",       128, 96 },
1169                 {NULL,          0, 0 },
1170         };
1171         if (*s == '<' || *s == '>')
1172                 sscanf(s+1,"%dx%d", &w, &h);
1173         for (fp = formats; fp->s; fp++) {
1174                 if (*s == '>') {        /* look for a larger one */
1175                         if (fp->w <= w) {
1176                                 if (fp > formats)
1177                                         fp--; /* back one step if possible */
1178                                 break;
1179                         }
1180                 } else if (*s == '<') { /* look for a smaller one */
1181                         if (fp->w < w)
1182                                 break;
1183                 } else if (!strcasecmp(s, fp->s)) { /* look for a string */
1184                         break;
1185                 }
1186         }
1187         if (*s == '<' && fp->s == NULL) /* smallest */
1188                 fp--;
1189         if (fp->s) {
1190                 b->w = fp->w;
1191                 b->h = fp->h;
1192         } else if (sscanf(s, "%dx%d", &b->w, &b->h) != 2) {
1193                 ast_log(LOG_WARNING, "Invalid video_size %s, using 352x288\n", s);
1194                 b->w = 352;
1195                 b->h = 288;
1196         }
1197         return 0;
1198 }
1199
1200 /* extend ast_cli with video commands. Called by console_video_config */
1201 int console_video_cli(struct video_desc *env, const char *var, int fd)
1202 {
1203         if (env == NULL)
1204                 return 1;       /* unrecognised */
1205
1206         if (!strcasecmp(var, "videodevice")) {
1207                 ast_cli(fd, "videodevice is [%s]\n", env->out.videodevice);
1208         } else if (!strcasecmp(var, "videocodec")) {
1209                 ast_cli(fd, "videocodec is [%s]\n", env->codec_name);
1210         } else if (!strcasecmp(var, "sendvideo")) {
1211                 ast_cli(fd, "sendvideo is [%s]\n", env->out.sendvideo ? "on" : "off");
1212         } else if (!strcasecmp(var, "video_size")) {
1213                 int in_w = 0, in_h = 0;
1214                 if (env->in) {
1215                         in_w = env->in->dec_out.w;
1216                         in_h = env->in->dec_out.h;
1217                 }
1218                 ast_cli(fd, "sizes: video %dx%d camera %dx%d local %dx%d remote %dx%d in %dx%d\n",
1219                         env->enc_in.w, env->enc_in.h,
1220                         env->out.loc_src_geometry.w, env->out.loc_src_geometry.h,
1221                         env->loc_dpy.w, env->loc_dpy.h,
1222                         env->rem_dpy.w, env->rem_dpy.h,
1223                         in_w, in_h);
1224         } else if (!strcasecmp(var, "bitrate")) {
1225                 ast_cli(fd, "bitrate is [%d]\n", env->out.bitrate);
1226         } else if (!strcasecmp(var, "qmin")) {
1227                 ast_cli(fd, "qmin is [%d]\n", env->out.qmin);
1228         } else if (!strcasecmp(var, "fps")) {
1229                 ast_cli(fd, "fps is [%d]\n", env->out.fps);
1230         } else {
1231                 return 1;       /* unrecognised */
1232         }
1233         return 0;       /* recognised */
1234 }
1235
1236 /*! parse config command for video support. */
1237 int console_video_config(struct video_desc **penv,
1238         const char *var, const char *val)
1239 {
1240         struct video_desc *env;
1241
1242         if (penv == NULL) {
1243                 ast_log(LOG_WARNING, "bad argument penv=NULL\n");
1244                 return 1;       /* error */
1245         }
1246         /* allocate the video descriptor first time we get here */
1247         env = *penv;
1248         if (env == NULL) {
1249                 env = *penv = ast_calloc(1, sizeof(struct video_desc));
1250                 if (env == NULL) {
1251                         ast_log(LOG_WARNING, "fail to allocate video_desc\n");
1252                         return 1;       /* error */
1253                 
1254                 }
1255                 /* set default values */
1256                 ast_copy_string(env->out.videodevice, "X11", sizeof(env->out.videodevice));
1257                 env->out.fps = 5;
1258                 env->out.bitrate = 65000;
1259                 env->out.sendvideo = 1;
1260                 env->out.qmin = 3;
1261         }
1262         CV_START(var, val);
1263         CV_STR("videodevice", env->out.videodevice);
1264         CV_BOOL("sendvideo", env->out.sendvideo);
1265         CV_F("video_size", video_geom(&env->enc_in, val));
1266         CV_F("camera_size", video_geom(&env->out.loc_src_geometry, val));
1267         CV_F("local_size", video_geom(&env->loc_dpy, val));
1268         CV_F("remote_size", video_geom(&env->rem_dpy, val));
1269         CV_STR("keypad", env->keypad_file);
1270         CV_F("region", keypad_cfg_read(env->gui, val));
1271         CV_STR("keypad_font", env->keypad_font);
1272         CV_STR("sdl_videodriver", env->sdl_videodriver);
1273         CV_UINT("fps", env->out.fps);
1274         CV_UINT("bitrate", env->out.bitrate);
1275         CV_UINT("qmin", env->out.qmin);
1276         CV_STR("videocodec", env->codec_name);
1277         return 1;       /* nothing found */
1278
1279         CV_END;         /* the 'nothing found' case */
1280         return 0;               /* found something */
1281 }
1282
1283 #endif  /* video support */