diff options
author | Patrick McHardy <kaber@trash.net> | 2011-07-06 04:52:35 +0200 |
---|---|---|
committer | Patrick McHardy <kaber@trash.net> | 2011-07-06 04:52:35 +0200 |
commit | 916e420bf0c8db7a8cb1f60557cd2807652142cf (patch) | |
tree | ece8aaf3f22e6e1cc545a858cad9e05c34713426 /main/bridging.c | |
parent | 9364aaccb699c6d19ac2cbe760c208b34ba7838a (diff) | |
parent | 357b97fb29d196a5f336d6a2879278ea135ab08c (diff) |
Merge branch 'master' of 192.168.0.100:/repos/git/asterisk
Diffstat (limited to 'main/bridging.c')
-rw-r--r-- | main/bridging.c | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/main/bridging.c b/main/bridging.c index 444eea8d5..1563e4789 100644 --- a/main/bridging.c +++ b/main/bridging.c @@ -50,6 +50,8 @@ static AST_RWLIST_HEAD_STATIC(bridge_technologies, ast_bridge_technology); /* Grow rate of bridge array of channels */ #define BRIDGE_ARRAY_GROW 32 +static void cleanup_video_mode(struct ast_bridge *bridge); + /*! Default DTMF keys for built in features */ static char builtin_features_dtmf[AST_BRIDGE_BUILTIN_END][MAXIMUM_DTMF_FEATURE_STRING]; @@ -457,6 +459,8 @@ static void destroy_bridge(void *obj) /* Drop the array of channels */ ast_free(bridge->array); + cleanup_video_mode(bridge); + return; } @@ -1470,3 +1474,116 @@ void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int bridge->internal_sample_rate = sample_rate; ao2_unlock(bridge); } + +static void cleanup_video_mode(struct ast_bridge *bridge) +{ + switch (bridge->video_mode.mode) { + case AST_BRIDGE_VIDEO_MODE_NONE: + break; + case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: + if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) { + ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc); + } + break; + case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: + if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) { + ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc); + } + } + memset(&bridge->video_mode, 0, sizeof(bridge->video_mode)); +} + +void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan) +{ + ao2_lock(bridge); + cleanup_video_mode(bridge); + bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_SINGLE_SRC; + bridge->video_mode.mode_data.single_src_data.chan_vsrc = ast_channel_ref(video_src_chan); + ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE); + ao2_unlock(bridge); +} + +void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge) +{ + ao2_lock(bridge); + cleanup_video_mode(bridge); + bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_TALKER_SRC; + ao2_unlock(bridge); +} + +void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe) +{ + struct ast_bridge_video_talker_src_data *data; + /* If the channel doesn't support video, we don't care about it */ + if (!ast_format_cap_has_type(chan->nativeformats, AST_FORMAT_TYPE_VIDEO)) { + return; + } + + ao2_lock(bridge); + data = &bridge->video_mode.mode_data.talker_src_data; + + if (data->chan_vsrc == chan) { + data->average_talking_energy = talker_energy; + } else if ((data->average_talking_energy < talker_energy) && is_keyframe) { + if (data->chan_vsrc) { + ast_channel_unref(data->chan_vsrc); + } + data->chan_vsrc = ast_channel_ref(chan); + data->average_talking_energy = talker_energy; + ast_indicate(chan, AST_CONTROL_VIDUPDATE); + } else if ((data->average_talking_energy < talker_energy) && !is_keyframe) { + ast_indicate(chan, AST_CONTROL_VIDUPDATE); + } else if (!data->chan_vsrc && is_keyframe) { + data->chan_vsrc = ast_channel_ref(chan); + data->average_talking_energy = talker_energy; + ast_indicate(chan, AST_CONTROL_VIDUPDATE); + } + ao2_unlock(bridge); +} + +int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan) +{ + int res = 0; + + ao2_lock(bridge); + switch (bridge->video_mode.mode) { + case AST_BRIDGE_VIDEO_MODE_NONE: + break; + case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: + if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) { + res = 1; + } + break; + case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: + if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) { + res = 1; + } + } + ao2_unlock(bridge); + return res; +} + +void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan) +{ + ao2_lock(bridge); + switch (bridge->video_mode.mode) { + case AST_BRIDGE_VIDEO_MODE_NONE: + break; + case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: + if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) { + if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) { + ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc); + } + bridge->video_mode.mode_data.single_src_data.chan_vsrc = NULL; + } + break; + case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: + if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) { + if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) { + ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc); + } + bridge->video_mode.mode_data.talker_src_data.chan_vsrc = NULL; + } + } + ao2_unlock(bridge); +} |