aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--channels/Makefile2
-rw-r--r--channels/chan_oss.c64
-rw-r--r--channels/console_video.c116
-rw-r--r--channels/console_video.h48
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 */