diff --git a/channels/console_video.c b/channels/console_video.c index e23fe7916..4cc0809d3 100644 --- a/channels/console_video.c +++ b/channels/console_video.c @@ -198,6 +198,7 @@ struct video_out_desc { struct video_desc { char codec_name[64]; /* the codec we use */ + int stayopen; /* set if gui starts manually */ pthread_t vthread; /* video thread */ ast_mutex_t dec_lock; /* sync decoder and video thread */ int shutdown; /* set to shutdown vthread */ @@ -432,7 +433,10 @@ static int video_out_init(struct video_desc *env) 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 * complete, giving up if it gets stuck. Because uninit * 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) { int i, t = 100; /* initial wait is shorter, than make it longer */ - env->shutdown = 1; - for (i=0; env->shutdown && i < 10; i++) { - ast_channel_unlock(env->owner); - usleep(t); - t = 1000000; - ast_channel_lock(env->owner); - } - env->owner = NULL; + if (env->stayopen == 0) { /* in a call */ + env->shutdown = 1; + for (i=0; env->shutdown && i < 10; i++) { + if (env->owner) + ast_channel_unlock(env->owner); + usleep(t); + t = 1000000; + 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 @@ -713,8 +721,8 @@ static void *video_thread(void *arg) for (;;) { struct timeval t = { 0, 50000 }; /* XXX 20 times/sec */ struct ast_frame *p, *f; - struct ast_channel *chan = env->owner; - int fd = chan->alertpipe[1]; + struct ast_channel *chan; + int fd; char *caption = NULL, buf[160]; sprintf(buf, "%d \r", count); @@ -774,6 +782,9 @@ static void *video_thread(void *arg) if (!f) continue; chan = env->owner; + if (chan == NULL) + continue; + fd = chan->alertpipe[1]; ast_channel_lock(chan); /* 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) { + ast_log(LOG_WARNING, "env %p chan %p\n", env, owner); if (env == NULL) /* video not initialized */ return; - if (owner == NULL) /* nothing to do if we don't have a channel */ - return; - env->owner = owner; + env->owner = owner; /* work even if no owner is specified */ + if (env->stayopen) + return; /* already initialized, nothing to do */ init_env(env); 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; ast_log(LOG_WARNING, "bitrate unset, forcing to %d\n", env->out.bitrate); } - 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); } else if (!strcasecmp(var, "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 { return 1; /* unrecognised */ } diff --git a/channels/console_video.h b/channels/console_video.h index beea23cb6..3d3975a67 100644 --- a/channels/console_video.h +++ b/channels/console_video.h @@ -33,12 +33,12 @@ #include /* requires a recent ffmpeg */ #endif -#define CONSOLE_VIDEO_CMDS \ - "console {videodevice|videocodec|sendvideo" \ - "|video_size|bitrate|fps|qmin" \ - "|keypad|keypad_mask|keypad_entry" \ - "|sdl_videodriver" \ - "|device" \ +#define CONSOLE_VIDEO_CMDS \ + "console {videodevice|videocodec" \ + "|video_size|bitrate|fps|qmin" \ + "|sendvideo|keypad" \ + "|sdl_videodriver" \ + "|device|startgui|stopgui" \ "}" #endif /* HAVE_VIDEO_CONSOLE and others */