implement the "console startgui" and "console stopgui"

commands so you can start and stop the gui even outside
of a call. This is convenient for testing, and also for
using the keypad to pick up a call, and to dial a number
(the latter not yet implemented, but should be close).



git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@97390 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.6.0
Luigi Rizzo 18 years ago
parent bbbef73276
commit b4fbb1916d

@ -198,6 +198,7 @@ struct video_out_desc {
struct video_desc { struct video_desc {
char codec_name[64]; /* the codec we use */ char codec_name[64]; /* the codec we use */
int stayopen; /* set if gui starts manually */
pthread_t vthread; /* video thread */ pthread_t vthread; /* video thread */
ast_mutex_t dec_lock; /* sync decoder and video thread */ ast_mutex_t dec_lock; /* sync decoder and video thread */
int shutdown; /* set to shutdown vthread */ int shutdown; /* set to shutdown vthread */
@ -432,7 +433,10 @@ static int video_out_init(struct video_desc *env)
return 0; return 0;
} }
/*! \brief uninitialize the entire environment. /*! \brief possibly uninitialize the video console.
* Called at the end of a call, should reset the 'owner' field,
* then possibly terminate the video thread if the gui has
* not been started manually.
* In practice, signal the thread and give it a bit of time to * In practice, signal the thread and give it a bit of time to
* complete, giving up if it gets stuck. Because uninit * complete, giving up if it gets stuck. Because uninit
* is called from hangup with the channel locked, and the thread * is called from hangup with the channel locked, and the thread
@ -442,14 +446,18 @@ static int video_out_init(struct video_desc *env)
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 */ int i, t = 100; /* initial wait is shorter, than make it longer */
env->shutdown = 1; if (env->stayopen == 0) { /* in a call */
for (i=0; env->shutdown && i < 10; i++) { env->shutdown = 1;
ast_channel_unlock(env->owner); for (i=0; env->shutdown && i < 10; i++) {
usleep(t); if (env->owner)
t = 1000000; ast_channel_unlock(env->owner);
ast_channel_lock(env->owner); usleep(t);
} t = 1000000;
env->owner = NULL; if (env->owner)
ast_channel_lock(env->owner);
}
}
env->owner = NULL; /* this is unconditional */
} }
/*! fill an AVPicture from our fbuf info, as it is required by /*! fill an AVPicture from our fbuf info, as it is required by
@ -713,8 +721,8 @@ static void *video_thread(void *arg)
for (;;) { for (;;) {
struct timeval t = { 0, 50000 }; /* XXX 20 times/sec */ struct timeval t = { 0, 50000 }; /* XXX 20 times/sec */
struct ast_frame *p, *f; struct ast_frame *p, *f;
struct ast_channel *chan = env->owner; struct ast_channel *chan;
int fd = chan->alertpipe[1]; int fd;
char *caption = NULL, buf[160]; char *caption = NULL, buf[160];
sprintf(buf, "%d \r", count); sprintf(buf, "%d \r", count);
@ -774,6 +782,9 @@ static void *video_thread(void *arg)
if (!f) if (!f)
continue; continue;
chan = env->owner; chan = env->owner;
if (chan == NULL)
continue;
fd = chan->alertpipe[1];
ast_channel_lock(chan); ast_channel_lock(chan);
/* AST_LIST_INSERT_TAIL is only good for one frame, cannot use here */ /* AST_LIST_INSERT_TAIL is only good for one frame, cannot use here */
@ -850,11 +861,12 @@ static void init_env(struct video_desc *env)
*/ */
void console_video_start(struct video_desc *env, struct ast_channel *owner) void console_video_start(struct video_desc *env, struct ast_channel *owner)
{ {
ast_log(LOG_WARNING, "env %p chan %p\n", env, owner);
if (env == NULL) /* video not initialized */ if (env == NULL) /* video not initialized */
return; return;
if (owner == NULL) /* nothing to do if we don't have a channel */ env->owner = owner; /* work even if no owner is specified */
return; if (env->stayopen)
env->owner = owner; return; /* already initialized, nothing to do */
init_env(env); init_env(env);
env->out.enc = map_config_video_format(env->codec_name); env->out.enc = map_config_video_format(env->codec_name);
@ -877,8 +889,9 @@ void console_video_start(struct video_desc *env, struct ast_channel *owner)
env->out.bitrate = 65000; env->out.bitrate = 65000;
ast_log(LOG_WARNING, "bitrate unset, forcing to %d\n", env->out.bitrate); ast_log(LOG_WARNING, "bitrate unset, forcing to %d\n", env->out.bitrate);
} }
ast_pthread_create_background(&env->vthread, NULL, video_thread, env); ast_pthread_create_background(&env->vthread, NULL, video_thread, env);
if (env->owner == NULL)
env->stayopen = 1; /* manually opened so don't close on hangup */
} }
/* /*
@ -963,6 +976,14 @@ int console_video_cli(struct video_desc *env, const char *var, int fd)
ast_cli(fd, "qmin is [%d]\n", env->out.qmin); ast_cli(fd, "qmin is [%d]\n", env->out.qmin);
} else if (!strcasecmp(var, "fps")) { } else if (!strcasecmp(var, "fps")) {
ast_cli(fd, "fps is [%d]\n", env->out.fps); ast_cli(fd, "fps is [%d]\n", env->out.fps);
} else if (!strcasecmp(var, "startgui")) {
console_video_start(env, NULL);
} else if (!strcasecmp(var, "stopgui") && env->stayopen != 0) {
env->stayopen = 0;
if (env->gui && env->owner)
ast_cli_command(-1, "console hangup");
else /* not in a call */
console_video_uninit(env);
} else { } else {
return 1; /* unrecognised */ return 1; /* unrecognised */
} }

@ -33,12 +33,12 @@
#include <ffmpeg/swscale.h> /* requires a recent ffmpeg */ #include <ffmpeg/swscale.h> /* requires a recent ffmpeg */
#endif #endif
#define CONSOLE_VIDEO_CMDS \ #define CONSOLE_VIDEO_CMDS \
"console {videodevice|videocodec|sendvideo" \ "console {videodevice|videocodec" \
"|video_size|bitrate|fps|qmin" \ "|video_size|bitrate|fps|qmin" \
"|keypad|keypad_mask|keypad_entry" \ "|sendvideo|keypad" \
"|sdl_videodriver" \ "|sdl_videodriver" \
"|device" \ "|device|startgui|stopgui" \
"}" "}"
#endif /* HAVE_VIDEO_CONSOLE and others */ #endif /* HAVE_VIDEO_CONSOLE and others */

Loading…
Cancel
Save