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