diff options
-rw-r--r-- | channels/Makefile | 2 | ||||
-rw-r--r-- | channels/chan_oss.c | 64 | ||||
-rw-r--r-- | channels/console_video.c | 116 | ||||
-rw-r--r-- | channels/console_video.h | 48 |
4 files changed, 150 insertions, 80 deletions
diff --git a/channels/Makefile b/channels/Makefile index c02bbebf9..50df82c58 100644 --- a/channels/Makefile +++ b/channels/Makefile @@ -51,6 +51,8 @@ endif all: _all +chan_oss.so: console_video.o + include $(ASTTOPDIR)/Makefile.moddir_rules ifneq ($(findstring $(OSARCH), mingw32 cygwin ),) diff --git a/channels/chan_oss.c b/channels/chan_oss.c index 14e6cdcce..460d095fb 100644 --- a/channels/chan_oss.c +++ b/channels/chan_oss.c @@ -63,6 +63,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/musiconhold.h" #include "asterisk/app.h" +#include "console_video.h" + /* ringtones we use */ #include "busy.h" #include "ringtone.h" @@ -268,8 +270,6 @@ static struct sound sounds[] = { { -1, NULL, 0, 0, 0, 0 }, /* end marker */ }; -struct video_desc; /* opaque type for video support */ - /*! * \brief descriptor for one of our channels. * @@ -350,7 +350,7 @@ struct chan_oss_pvt { static struct chan_oss_pvt *find_desc(char *dev); /*! \brief return the pointer to the video descriptor */ -static attribute_unused struct video_desc *get_video_desc(struct ast_channel *c) +struct video_desc *get_video_desc(struct ast_channel *c) { struct chan_oss_pvt *o = c->tech_pvt; return o ? o->env : NULL; @@ -388,24 +388,11 @@ static int oss_indicate(struct ast_channel *chan, int cond, const void *data, si static int oss_fixup(struct ast_channel *oldchan, struct ast_channel *newchan); static char tdesc[] = "OSS Console Channel Driver"; -#ifdef HAVE_VIDEO_CONSOLE -#include "console_video.c" -#else -#define CONSOLE_VIDEO_CMDS \ - "console {device}" -/* provide replacements for some symbols used */ -#define console_write_video NULL -#define console_video_start(x, y) {} -#define console_video_uninit(x) {} -#define console_video_config(x, y, z) 1 /* pretend nothing recognised */ -#define console_video_cli(x, y, z) 0 /* pretend nothing recognised */ -#define CONSOLE_FORMAT_VIDEO 0 -#endif - -static const struct ast_channel_tech oss_tech = { +/* cannot do const because need to update some fields at runtime */ +static struct ast_channel_tech oss_tech = { .type = "Console", .description = tdesc, - .capabilities = AST_FORMAT_SLINEAR | CONSOLE_FORMAT_VIDEO, + .capabilities = AST_FORMAT_SLINEAR, /* overwritten later */ .requester = oss_request, .send_digit_begin = oss_digit_begin, .send_digit_end = oss_digit_end, @@ -1017,7 +1004,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *o, char *ext, char *ctx, c->nativeformats = AST_FORMAT_SLINEAR; /* if the console makes the call, add video to the offer */ if (state == AST_STATE_RINGING) - c->nativeformats |= CONSOLE_FORMAT_VIDEO; + c->nativeformats |= console_video_formats; c->readformat = AST_FORMAT_SLINEAR; c->writeformat = AST_FORMAT_SLINEAR; @@ -1114,7 +1101,7 @@ static char *console_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args * value = a->argc > e->args ? a->argv[e->args] : NULL; if (value) /* handle setting */ store_config_core(o, var, value); - if (console_video_cli(o->env, var, a->fd)) /* print video-related values */ + if (!console_video_cli(o->env, var, a->fd)) /* print video-related values */ return CLI_SUCCESS; /* handle other values */ if (!strcasecmp(var, "device")) { @@ -1161,14 +1148,29 @@ static char *console_autoanswer(struct ast_cli_entry *e, int cmd, struct ast_cli return CLI_SUCCESS; } +/*! \brief helper function for the answer key/cli command */ +char *console_do_answer(int fd); +char *console_do_answer(int fd) +{ + struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; + struct chan_oss_pvt *o = find_desc(oss_active); + if (!o->owner) { + if (fd > -1) + ast_cli(fd, "No one is calling us\n"); + return CLI_FAILURE; + } + o->hookstate = 1; + o->cursound = -1; + o->nosound = 0; + ast_queue_frame(o->owner, &f); + return CLI_SUCCESS; +} + /*! * \brief answer command from the console */ static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { - struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; - struct chan_oss_pvt *o = find_desc(oss_active); - switch (cmd) { case CLI_INIT: e->command = "console answer"; @@ -1182,15 +1184,7 @@ static char *console_answer(struct ast_cli_entry *e, int cmd, struct ast_cli_arg } if (a->argc != e->args) return CLI_SHOWUSAGE; - if (!o->owner) { - ast_cli(a->fd, "No one is calling us\n"); - return CLI_FAILURE; - } - o->hookstate = 1; - o->cursound = -1; - o->nosound = 0; - ast_queue_frame(o->owner, &f); - return CLI_SUCCESS; + return console_do_answer(a->fd); } /*! @@ -1538,7 +1532,7 @@ static void store_config_core(struct chan_oss_pvt *o, const char *var, const cha return; if (!console_video_config(&o->env, var, value)) - return; + return; /* matched there */ CV_BOOL("autoanswer", o->autoanswer); CV_BOOL("autohangup", o->autohangup); CV_BOOL("overridecontext", o->overridecontext); @@ -1657,6 +1651,8 @@ static int load_module(void) return AST_MODULE_LOAD_FAILURE; } + oss_tech.capabilities |= console_video_formats; + if (ast_channel_register(&oss_tech)) { ast_log(LOG_ERROR, "Unable to register channel type 'OSS'\n"); return AST_MODULE_LOAD_FAILURE; diff --git a/channels/console_video.c b/channels/console_video.c index d59d3bb77..f35813e3c 100644 --- a/channels/console_video.c +++ b/channels/console_video.c @@ -20,6 +20,14 @@ //#define DROP_PACKETS 5 /* if set, drop this % of video packets */ //#define OLD_FFMPEG 1 /* set for old ffmpeg with no swscale */ +#include "asterisk.h" +#include <sys/ioctl.h> +#include <math.h> /* sqrt */ +#include "asterisk/cli.h" +#include "asterisk/file.h" +#include "asterisk/channel.h" + +#include "console_video.h" /* The code is structured as follows. @@ -84,7 +92,40 @@ iax.conf too) the following: * In principle SDL is optional too (used for rendering only, but we * could still source data withouth it), however at the moment it is required. */ -#if defined(HAVE_FFMPEG) && defined(HAVE_SDL) +#if !defined(HAVE_VIDEO_CONSOLE) || !defined(HAVE_FFMPEG) || !defined(HAVE_SDL) +/* stubs if required pieces are missing */ +int console_write_video(struct ast_channel *chan, struct ast_frame *f) +{ + return 0; /* writing video not supported */ +} + +int console_video_cli(struct video_desc *env, const char *var, int fd) +{ + return 1; /* nothing matched */ +} + +int console_video_config(struct video_desc **penv, const char *var, const char *val) +{ + return 1; /* no configuration */ +} + +void console_video_start(struct video_desc *env, struct ast_channel *owner) +{ + ast_log(LOG_WARNING, "console video support not present\n"); +} + +void console_video_uninit(struct video_desc *env) +{ +} + +int console_video_formats = 0; + +#else /* defined(HAVE_FFMPEG) && defined(HAVE_SDL) */ + +/*! The list of video formats we support. */ +int console_video_formats = + AST_FORMAT_H263_PLUS | AST_FORMAT_H263 | + AST_FORMAT_MP4_VIDEO | AST_FORMAT_H264 | AST_FORMAT_H261 ; #ifdef HAVE_X11 #include <X11/Xlib.h> /* this should be conditional */ @@ -304,12 +345,6 @@ struct video_desc { struct display_window win[WIN_MAX]; }; -/*! The list of video formats we support. */ -#define CONSOLE_FORMAT_VIDEO ( \ - AST_FORMAT_H263_PLUS | AST_FORMAT_H263 | \ - AST_FORMAT_MP4_VIDEO | \ - AST_FORMAT_H264 | AST_FORMAT_H261) - static AVPicture *fill_pict(struct fbuf_t *b, AVPicture *p); static void fbuf_free(struct fbuf_t *b) @@ -1867,7 +1902,7 @@ static void cleanup_sdl(struct video_desc *env) * uses the chan lock, we need to unlock here. This is unsafe, * and we should really use refcounts for the channels. */ -static void console_video_uninit(struct video_desc *env) +void console_video_uninit(struct video_desc *env) { int i, t = 100; /* initial wait is shorter, than make it longer */ env->shutdown = 1; @@ -2011,7 +2046,7 @@ static void show_frame(struct video_desc *env, int out) SDL_UnlockYUVOverlay(bmp); } -static struct video_desc *get_video_desc(struct ast_channel *c); +struct video_desc *get_video_desc(struct ast_channel *c); /* * This function is called (by asterisk) for each video packet @@ -2023,7 +2058,8 @@ static struct video_desc *get_video_desc(struct ast_channel *c); * - if the fragment is the last (RTP Marker) we decode it with decode_video() * - after the decoding is completed we display the decoded frame with show_frame() */ -static int console_write_video(struct ast_channel *chan, struct ast_frame *f) +int console_write_video(struct ast_channel *chan, struct ast_frame *f); +int console_write_video(struct ast_channel *chan, struct ast_frame *f) { struct video_desc *env = get_video_desc(chan); struct video_in_desc *v = &env->in; @@ -2236,13 +2272,11 @@ static void append_char(char *str, int *str_pos, const char c) /* accumulate digits, possibly call dial if in connected mode */ static void keypad_digit(struct video_desc *env, int digit) { - struct chan_oss_pvt *o = find_desc(oss_active); - - if (o->owner) { /* we have a call, send the digit */ + if (env->owner) { /* we have a call, send the digit */ struct ast_frame f = { AST_FRAME_DTMF, 0 }; f.subclass = digit; - ast_queue_frame(o->owner, &f); + ast_queue_frame(env->owner, &f); } else { /* no call, accumulate digits */ append_char(env->gui.inbuf, &env->gui.inbuf_pos, digit); } @@ -2258,25 +2292,31 @@ static void keypad_send_command(struct video_desc *env, char *command) } /* function used to toggle on/off the status of some variables */ -static char *keypad_toggle(int index) +static char *keypad_toggle(struct video_desc *env, int index) { - struct chan_oss_pvt *o = find_desc(oss_active); ast_log(LOG_WARNING, "keypad_toggle(%i) called\n", index); switch (index) { - case KEY_MUTE: - o->mute = !o->mute; - break; case KEY_SENDVIDEO: - o->env->out.sendvideo = !o->env->out.sendvideo; + env->out.sendvideo = !env->out.sendvideo; break; - case KEY_AUTOANSWER: +#ifdef notyet + case KEY_MUTE: { + struct chan_oss_pvt *o = find_desc(oss_active); + o->mute = !o->mute; + } + break; + case KEY_AUTOANSWER: { + struct chan_oss_pvt *o = find_desc(oss_active); o->autoanswer = !o->autoanswer; + } break; +#endif } return NULL; } +char *console_do_answer(int fd); /* * Function called when the pick up button is pressed * perform actions according the channel status: @@ -2289,15 +2329,10 @@ static char *keypad_toggle(int index) */ static void keypad_pick_up(struct video_desc *env) { - struct chan_oss_pvt *o = find_desc(oss_active); ast_log(LOG_WARNING, "keypad_pick_up called\n"); - if (o->owner) { /* someone is calling us, just answer */ - struct ast_frame f = { AST_FRAME_CONTROL, AST_CONTROL_ANSWER }; - o->hookstate = 1; - o->cursound = -1; - o->nosound = 0; - ast_queue_frame(o->owner, &f); + if (env->owner) { /* someone is calling us, just answer */ + console_do_answer(-1); } else if (env->gui.inbuf_pos) { /* we have someone to call */ ast_cli_command(env->gui.outfd, env->gui.inbuf); } @@ -2404,7 +2439,7 @@ static void handle_button_event(struct video_desc *env, SDL_MouseButtonEvent but case KEY_MUTE: case KEY_AUTOANSWER: case KEY_SENDVIDEO: - keypad_toggle(index); + keypad_toggle(env, index); break; case KEY_LOCALVIDEO: @@ -2822,8 +2857,7 @@ static int set_win(SDL_Surface *screen, struct display_window *win, int fmt, * We do our best to progress even if some of the components are not * available. */ -static void console_video_start(struct video_desc *env, - struct ast_channel *owner) +void console_video_start(struct video_desc *env, struct ast_channel *owner) { if (env == NULL) /* video not initialized */ return; @@ -3187,21 +3221,11 @@ static int keypad_cfg_read(struct gui_info *gui, const char *val) return 1; } -/* list of commands supported by the cli. - * For write operation we use the commands in console_video_config(), - * for reads we use console_video_cli(). XXX Names should be fixed. - */ -#define CONSOLE_VIDEO_CMDS \ - "console {videodevice|videocodec|sendvideo" \ - "|video_size|bitrate|fps|qmin" \ - "|keypad|keypad_mask|keypad_entry" \ - "}" - /* extend ast_cli with video commands. Called by console_video_config */ -static int console_video_cli(struct video_desc *env, const char *var, int fd) +int console_video_cli(struct video_desc *env, const char *var, int fd) { if (env == NULL) - return 0; /* unrecognised */ + return 1; /* unrecognised */ if (!strcasecmp(var, "videodevice")) { ast_cli(fd, "videodevice is [%s]\n", env->out.videodevice); @@ -3223,13 +3247,13 @@ static int console_video_cli(struct video_desc *env, const char *var, int fd) } else if (!strcasecmp(var, "fps")) { ast_cli(fd, "fps is [%d]\n", env->out.fps); } else { - return 0; /* unrecognised */ + return 1; /* unrecognised */ } - return 1; /* recognised */ + return 0; /* recognised */ } /*! parse config command for video support. */ -static int console_video_config(struct video_desc **penv, +int console_video_config(struct video_desc **penv, const char *var, const char *val) { struct video_desc *env; diff --git a/channels/console_video.h b/channels/console_video.h new file mode 100644 index 000000000..cb627a197 --- /dev/null +++ b/channels/console_video.h @@ -0,0 +1,48 @@ +/* + * Asterisk -- An open source telephony toolkit. + * + * Copyright (C) 2007 Luigi Rizzo + * + * See http://www.asterisk.org for more information about + * the Asterisk project. Please do not directly contact + * any of the maintainers of this project for assistance; + * the project provides a web site, mailing lists and IRC + * channels for your use. + * + * This program is free software, distributed under the terms of + * the GNU General Public License Version 2. See the LICENSE file + * at the top of the source tree. + */ + +/* + * Common header for console video support + * + * $Revision$ + */ + +struct video_desc; /* opaque type for video support */ + +struct video_desc *get_video_desc(struct ast_channel *c); + +/* linked by console_video.o */ +int console_write_video(struct ast_channel *chan, struct ast_frame *f); +extern int console_video_formats; +int console_video_cli(struct video_desc *env, const char *var, int fd); +int console_video_config(struct video_desc **penv, const char *var, const char *val); +void console_video_uninit(struct video_desc *env); +void console_video_start(struct video_desc *env, struct ast_channel *owner); + +#ifdef HAVE_VIDEO_CONSOLE +#define CONSOLE_VIDEO_CMDS \ + "console {videodevice|videocodec|sendvideo" \ + "|video_size|bitrate|fps|qmin" \ + "|keypad|keypad_mask|keypad_entry" \ + "|device" \ + "}" + +#else +#define CONSOLE_VIDEO_CMDS \ + "console {device}" +#endif + +/* end of file */ |