From 2db968139e780b63e6d11b52e11b125ddfc2ae8b Mon Sep 17 00:00:00 2001 From: dvossel Date: Thu, 7 Jul 2011 17:24:57 +0000 Subject: [PATCH] Updates confbridge.conf video documentation and adds dtmf action for releasing video src. git-svn-id: http://svn.digium.com/svn/asterisk/trunk@326782 f38db490-d61c-443f-a65b-d21fe96a405b --- apps/app_confbridge.c | 39 ++++++++++++++++++---------- apps/confbridge/conf_config_parser.c | 6 +++++ apps/confbridge/include/confbridge.h | 1 + configs/confbridge.conf.sample | 23 ++++++++++++++-- 4 files changed, 53 insertions(+), 16 deletions(-) diff --git a/apps/app_confbridge.c b/apps/app_confbridge.c index d046c489f..80c84ed47 100644 --- a/apps/app_confbridge.c +++ b/apps/app_confbridge.c @@ -632,10 +632,10 @@ static int play_prompt_to_channel(struct conference_bridge *conference_bridge, s return res; } -static void handle_video_on_join(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user) +static void handle_video_on_join(struct conference_bridge *conference_bridge, struct ast_channel *chan, int marked) { - /* only automatically set video source for marked users */ - if (!ast_test_flag(&conference_bridge_user->u_profile, USER_OPT_MARKEDUSER)) { + /* Right now, only marked users are automatically set as the single src of video.*/ + if (!marked) { return; } @@ -645,7 +645,7 @@ static void handle_video_on_join(struct conference_bridge *conference_bridge, st ao2_lock(conference_bridge); /* see if anyone is already the video src */ AST_LIST_TRAVERSE(&conference_bridge->users_list, tmp_user, list) { - if (tmp_user == conference_bridge_user) { + if (tmp_user->chan == chan) { continue; } if (ast_bridge_is_video_src(conference_bridge->bridge, tmp_user->chan)) { @@ -655,24 +655,31 @@ static void handle_video_on_join(struct conference_bridge *conference_bridge, st } ao2_unlock(conference_bridge); if (set) { - ast_bridge_set_single_src_video_mode(conference_bridge->bridge, conference_bridge_user->chan); + ast_bridge_set_single_src_video_mode(conference_bridge->bridge, chan); } } else if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_LAST_MARKED)) { /* we joined and are video capable, we override anyone else that may have already been the video feed */ - ast_bridge_set_single_src_video_mode(conference_bridge->bridge, conference_bridge_user->chan); + ast_bridge_set_single_src_video_mode(conference_bridge->bridge, chan); } } -static void handle_video_on_exit(struct conference_bridge *conference_bridge, struct conference_bridge_user *conference_bridge_user) +static void handle_video_on_exit(struct conference_bridge *conference_bridge, struct ast_channel *chan) { struct conference_bridge_user *tmp_user = NULL; /* if this isn't a video source, nothing to update */ - if (!ast_bridge_is_video_src(conference_bridge->bridge, conference_bridge_user->chan)) { + if (!ast_bridge_is_video_src(conference_bridge->bridge, chan)) { return; } - ast_bridge_remove_video_src(conference_bridge->bridge, conference_bridge_user->chan); + ast_bridge_remove_video_src(conference_bridge->bridge, chan); + + /* If in follow talker mode, make sure to restore this mode on the + * bridge when a source is removed. It is possible this channel was + * only set temporarily as a video source by an AMI or DTMF action. */ + if (ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FOLLOW_TALKER)) { + ast_bridge_set_talker_src_video_mode(conference_bridge->bridge); + } /* if the video_mode isn't set to automatically pick the video source, do nothing on exit. */ if (!ast_test_flag(&conference_bridge->b_profile, BRIDGE_OPT_VIDEO_SRC_FIRST_MARKED) && @@ -680,10 +687,10 @@ static void handle_video_on_exit(struct conference_bridge *conference_bridge, st return; } - /* Make the next avaliable marked user the video src. */ + /* Make the next available marked user the video src. */ ao2_lock(conference_bridge); AST_LIST_TRAVERSE(&conference_bridge->users_list, tmp_user, list) { - if (tmp_user == conference_bridge_user) { + if (tmp_user->chan == chan) { continue; } if (ast_test_flag(&tmp_user->u_profile, USER_OPT_MARKEDUSER)) { @@ -1454,7 +1461,8 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) } } - handle_video_on_join(conference_bridge, &conference_bridge_user); + /* See if we need to automatically set this user as a video source or not */ + handle_video_on_join(conference_bridge, conference_bridge_user.chan, ast_test_flag(&conference_bridge_user.u_profile, USER_OPT_MARKEDUSER)); /* Join our conference bridge for real */ send_join_event(conference_bridge_user.chan, conference_bridge->name); @@ -1465,8 +1473,8 @@ static int confbridge_exec(struct ast_channel *chan, const char *data) &conference_bridge_user.tech_args); send_leave_event(conference_bridge_user.chan, conference_bridge->name); - - handle_video_on_exit(conference_bridge, &conference_bridge_user); + /* If this user was a video source, we need to clean up and possibly pick a new source. */ + handle_video_on_exit(conference_bridge, conference_bridge_user.chan); /* if this user has a intro, play it when leaving */ if (!quiet && !ast_strlen_zero(conference_bridge_user.name_rec_location)) { @@ -1775,6 +1783,9 @@ static int execute_menu_entry(struct conference_bridge *conference_bridge, ast_bridge_set_single_src_video_mode(conference_bridge->bridge, bridge_channel->chan); ao2_unlock(conference_bridge); break; + case MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC: + handle_video_on_exit(conference_bridge, bridge_channel->chan); + break; } } return res; diff --git a/apps/confbridge/conf_config_parser.c b/apps/confbridge/conf_config_parser.c index 8864f52bc..d11b82582 100644 --- a/apps/confbridge/conf_config_parser.c +++ b/apps/confbridge/conf_config_parser.c @@ -543,6 +543,7 @@ static int add_action_to_menu_entry(struct conf_menu_entry *menu_entry, enum con case MENU_ACTION_ADMIN_KICK_LAST: case MENU_ACTION_LEAVE: case MENU_ACTION_SET_SINGLE_VIDEO_SRC: + case MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC: break; case MENU_ACTION_PLAYBACK: case MENU_ACTION_PLAYBACK_AND_CONTINUE: @@ -660,6 +661,8 @@ static int add_menu_entry(struct conf_menu *menu, const char *dtmf, const char * res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_LEAVE, NULL); } else if (!strcasecmp(action, "set_as_single_video_src")) { res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_SET_SINGLE_VIDEO_SRC, NULL); + } else if (!strcasecmp(action, "release_as_single_video_src")) { + res |= add_action_to_menu_entry(menu_entry, MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC, NULL); } else if (!strncasecmp(action, "dialplan_exec(", 14)) { ast_copy_string(buf, action, sizeof(buf)); action_args = buf; @@ -1166,6 +1169,9 @@ static char *handle_cli_confbridge_show_menu(struct ast_cli_entry *e, int cmd, s case MENU_ACTION_SET_SINGLE_VIDEO_SRC: ast_cli(a->fd, "set_as_single_video_src"); break; + case MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC: + ast_cli(a->fd, "release_as_single_video_src"); + break; } action_num++; } diff --git a/apps/confbridge/include/confbridge.h b/apps/confbridge/include/confbridge.h index 7a2f6bb07..ab4a8c4b0 100644 --- a/apps/confbridge/include/confbridge.h +++ b/apps/confbridge/include/confbridge.h @@ -82,6 +82,7 @@ enum conf_menu_action_id { MENU_ACTION_LEAVE, MENU_ACTION_NOOP, MENU_ACTION_SET_SINGLE_VIDEO_SRC, + MENU_ACTION_RELEASE_SINGLE_VIDEO_SRC, }; /*! The conference menu action contains both diff --git a/configs/confbridge.conf.sample b/configs/confbridge.conf.sample index 408387012..e60ba73be 100644 --- a/configs/confbridge.conf.sample +++ b/configs/confbridge.conf.sample @@ -168,9 +168,13 @@ type=bridge ; larger amounts of delay into the bridge. Valid values here are 10, 20, 40, ; or 80. By default 20ms is used. -;video_mode = follow_talker ; Sets how confbridge handles video distribution to the conference participants. +;video_mode = follow_talker; Sets how confbridge handles video distribution to the conference participants. ; Note that participants wanting to view and be the source of a video feed - ; _MUST_ be sharing the same video codec. + ; _MUST_ be sharing the same video codec. Also, using video in conjunction with + ; with the jitterbuffer currently results in the audio being slightly out of sync + ; with the video. This is a result of the jitterbuffer only working on the audio + ; stream. It is recommended to disable the jitterbuffer when video is used. + ; ; --- MODES --- ; none: No video sources are set by default in the conference. It is still ; possible for a user to be set as a video source via AMI or DTMF action @@ -284,8 +288,23 @@ type=bridge ; admin_toggle_conference_lock ; This action allows an Admin to toggle locking and ; unlocking the conference. Non admins can not use ; this action even if it is in their menu. + ; set_as_single_video_src ; This action allows any user to set themselves as the ; single video source distributed to all participants. + ; This will make the video feed stick to them regardless + ; of what the video_mode is set to. + +; release_as_single_video_src ; This action allows a user to release themselves as + ; the video source. If video_mode is not set to "none" + ; this action will result in the conference returning to + ; whatever video mode the bridge profile is using. + ; + ; Note that this action will have no effect if the user + ; is not currently the video source. Also, the user is + ; not guaranteed by using this action that they will not + ; become the video source again. The bridge will return + ; to whatever operation the video_mode option is set to + ; upon release of the video src. [sample_user_menu] type=menu