Pull softmix bridge parameters into a sub structure.

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@395188 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Richard Mudgett
2013-07-23 19:14:44 +00:00
parent 2598219adb
commit f087b69fc4
3 changed files with 71 additions and 54 deletions

View File

@@ -477,7 +477,7 @@ static void softmix_bridge_write_video(struct ast_bridge *bridge, struct ast_bri
int video_src_priority; int video_src_priority;
/* Determine if the video frame should be distributed or not */ /* Determine if the video frame should be distributed or not */
switch (bridge->video_mode.mode) { switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE: case AST_BRIDGE_VIDEO_MODE_NONE:
break; break;
case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
@@ -533,7 +533,7 @@ static void softmix_bridge_write_voice(struct ast_bridge *bridge, struct ast_bri
ast_mutex_lock(&sc->lock); ast_mutex_lock(&sc->lock);
ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy); ast_dsp_silence_with_energy(sc->dsp, frame, &totalsilence, &cur_energy);
if (bridge->video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) { if (bridge->softmix.video_mode.mode == AST_BRIDGE_VIDEO_MODE_TALKER_SRC) {
int cur_slot = sc->video_talker.energy_history_cur_slot; int cur_slot = sc->video_talker.energy_history_cur_slot;
sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot]; sc->video_talker.energy_accum -= sc->video_talker.energy_history[cur_slot];
@@ -851,7 +851,7 @@ static int softmix_mixing_loop(struct ast_bridge *bridge)
/* These variables help determine if a rate change is required */ /* These variables help determine if a rate change is required */
if (!stat_iteration_counter) { if (!stat_iteration_counter) {
memset(&stats, 0, sizeof(stats)); memset(&stats, 0, sizeof(stats));
stats.locked_rate = bridge->internal_sample_rate; stats.locked_rate = bridge->softmix.internal_sample_rate;
} }
/* If the sample rate has changed, update the translator helper */ /* If the sample rate has changed, update the translator helper */
@@ -942,8 +942,9 @@ static int softmix_mixing_loop(struct ast_bridge *bridge)
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
/* make sure to detect mixing interval changes if they occur. */ /* make sure to detect mixing interval changes if they occur. */
if (bridge->internal_mixing_interval && (bridge->internal_mixing_interval != softmix_data->internal_mixing_interval)) { if (bridge->softmix.internal_mixing_interval
softmix_data->internal_mixing_interval = bridge->internal_mixing_interval; && (bridge->softmix.internal_mixing_interval != softmix_data->internal_mixing_interval)) {
softmix_data->internal_mixing_interval = bridge->softmix.internal_mixing_interval;
ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval)); ast_timer_set_rate(timer, (1000 / softmix_data->internal_mixing_interval));
update_all_rates = 1; /* if the interval changes, the rates must be adjusted as well just to be notified new interval.*/ update_all_rates = 1; /* if the interval changes, the rates must be adjusted as well just to be notified new interval.*/
} }

View File

@@ -390,6 +390,26 @@ struct ast_bridge_methods {
ast_bridge_merge_priority_fn get_merge_priority; ast_bridge_merge_priority_fn get_merge_priority;
}; };
/*! Softmix technology parameters. */
struct ast_bridge_softmix {
/*! The video mode softmix is using */
struct ast_bridge_video_mode video_mode;
/*!
* \brief The internal sample rate softmix uses to mix channels.
*
* \note If this value is 0, the sofmix may auto adjust the mixing rate.
*/
unsigned int internal_sample_rate;
/*!
* \brief The mixing interval indicates how quickly softmix
* mixing should occur to mix audio.
*
* \note When set to 0, softmix must choose a default interval
* for itself.
*/
unsigned int internal_mixing_interval;
};
/*! /*!
* \brief Structure that contains information about a bridge * \brief Structure that contains information about a bridge
*/ */
@@ -398,8 +418,6 @@ struct ast_bridge {
const struct ast_bridge_methods *v_table; const struct ast_bridge_methods *v_table;
/*! "Personality" currently exhibited by bridge subclass */ /*! "Personality" currently exhibited by bridge subclass */
void *personality; void *personality;
/*! Immutable bridge UUID. */
char uniqueid[AST_UUID_STR_LEN];
/*! Bridge technology that is handling the bridge */ /*! Bridge technology that is handling the bridge */
struct ast_bridge_technology *technology; struct ast_bridge_technology *technology;
/*! Private information unique to the bridge technology */ /*! Private information unique to the bridge technology */
@@ -410,8 +428,8 @@ struct ast_bridge {
AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) channels; AST_LIST_HEAD_NOLOCK(, ast_bridge_channel) channels;
/*! Queue of actions to perform on the bridge. */ /*! Queue of actions to perform on the bridge. */
AST_LIST_HEAD_NOLOCK(, ast_frame) action_queue; AST_LIST_HEAD_NOLOCK(, ast_frame) action_queue;
/*! The video mode this bridge is using */ /*! Softmix technology parameters. */
struct ast_bridge_video_mode video_mode; struct ast_bridge_softmix softmix;
/*! Bridge flags to tweak behavior */ /*! Bridge flags to tweak behavior */
struct ast_flags feature_flags; struct ast_flags feature_flags;
/*! Allowed bridge technology capabilities when AST_BRIDGE_FLAG_SMART enabled. */ /*! Allowed bridge technology capabilities when AST_BRIDGE_FLAG_SMART enabled. */
@@ -427,19 +445,14 @@ struct ast_bridge {
* \note Temporary as in try again in a moment. * \note Temporary as in try again in a moment.
*/ */
unsigned int inhibit_merge; unsigned int inhibit_merge;
/*! The internal sample rate this bridge is mixed at when multiple channels are being mixed.
* If this value is 0, the bridge technology may auto adjust the internal mixing rate. */
unsigned int internal_sample_rate;
/*! The mixing interval indicates how quickly the bridges internal mixing should occur
* for bridge technologies that mix audio. When set to 0, the bridge tech must choose a
* default interval for itself. */
unsigned int internal_mixing_interval;
/*! TRUE if the bridge was reconfigured. */ /*! TRUE if the bridge was reconfigured. */
unsigned int reconfigured:1; unsigned int reconfigured:1;
/*! TRUE if the bridge has been dissolved. Any channel that now tries to join is immediately ejected. */ /*! TRUE if the bridge has been dissolved. Any channel that now tries to join is immediately ejected. */
unsigned int dissolved:1; unsigned int dissolved:1;
/*! TRUE if the bridge construction was completed. */ /*! TRUE if the bridge construction was completed. */
unsigned int construction_completed:1; unsigned int construction_completed:1;
/*! Immutable bridge UUID. */
char uniqueid[AST_UUID_STR_LEN];
}; };
/*! /*!

View File

@@ -5788,45 +5788,46 @@ struct ast_bridge_features *ast_bridge_features_new(void)
void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval) void ast_bridge_set_mixing_interval(struct ast_bridge *bridge, unsigned int mixing_interval)
{ {
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
bridge->internal_mixing_interval = mixing_interval; bridge->softmix.internal_mixing_interval = mixing_interval;
ast_bridge_unlock(bridge); ast_bridge_unlock(bridge);
} }
void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate) void ast_bridge_set_internal_sample_rate(struct ast_bridge *bridge, unsigned int sample_rate)
{ {
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
bridge->internal_sample_rate = sample_rate; bridge->softmix.internal_sample_rate = sample_rate;
ast_bridge_unlock(bridge); ast_bridge_unlock(bridge);
} }
static void cleanup_video_mode(struct ast_bridge *bridge) static void cleanup_video_mode(struct ast_bridge *bridge)
{ {
switch (bridge->video_mode.mode) { switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE: case AST_BRIDGE_VIDEO_MODE_NONE:
break; break;
case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc);
} }
break; break;
case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc);
} }
if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc);
} }
} }
memset(&bridge->video_mode, 0, sizeof(bridge->video_mode)); memset(&bridge->softmix.video_mode, 0, sizeof(bridge->softmix.video_mode));
} }
void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan) void ast_bridge_set_single_src_video_mode(struct ast_bridge *bridge, struct ast_channel *video_src_chan)
{ {
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
cleanup_video_mode(bridge); cleanup_video_mode(bridge);
bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_SINGLE_SRC; bridge->softmix.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); bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc = ast_channel_ref(video_src_chan);
ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to single source\r\nVideo Mode: %d\r\nVideo Channel: %s", bridge->video_mode.mode, ast_channel_name(video_src_chan)); ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to single source\r\nVideo Mode: %d\r\nVideo Channel: %s",
bridge->softmix.video_mode.mode, ast_channel_name(video_src_chan));
ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE); ast_indicate(video_src_chan, AST_CONTROL_VIDUPDATE);
ast_bridge_unlock(bridge); ast_bridge_unlock(bridge);
} }
@@ -5835,21 +5836,23 @@ void ast_bridge_set_talker_src_video_mode(struct ast_bridge *bridge)
{ {
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
cleanup_video_mode(bridge); cleanup_video_mode(bridge);
bridge->video_mode.mode = AST_BRIDGE_VIDEO_MODE_TALKER_SRC; bridge->softmix.video_mode.mode = AST_BRIDGE_VIDEO_MODE_TALKER_SRC;
ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to talker source\r\nVideo Mode: %d", bridge->video_mode.mode); ast_test_suite_event_notify("BRIDGE_VIDEO_MODE", "Message: video mode set to talker source\r\nVideo Mode: %d",
bridge->softmix.video_mode.mode);
ast_bridge_unlock(bridge); ast_bridge_unlock(bridge);
} }
void ast_bridge_update_talker_src_video_mode(struct ast_bridge *bridge, struct ast_channel *chan, int talker_energy, int is_keyframe) 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; struct ast_bridge_video_talker_src_data *data;
/* If the channel doesn't support video, we don't care about it */ /* If the channel doesn't support video, we don't care about it */
if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_VIDEO)) { if (!ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_FORMAT_TYPE_VIDEO)) {
return; return;
} }
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
data = &bridge->video_mode.mode_data.talker_src_data; data = &bridge->softmix.video_mode.mode_data.talker_src_data;
if (data->chan_vsrc == chan) { if (data->chan_vsrc == chan) {
data->average_talking_energy = talker_energy; data->average_talking_energy = talker_energy;
@@ -5884,19 +5887,19 @@ int ast_bridge_number_video_src(struct ast_bridge *bridge)
int res = 0; int res = 0;
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
switch (bridge->video_mode.mode) { switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE: case AST_BRIDGE_VIDEO_MODE_NONE:
break; break;
case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
res = 1; res = 1;
} }
break; break;
case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc) {
res++; res++;
} }
if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc) {
res++; res++;
} }
} }
@@ -5909,18 +5912,18 @@ int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
int res = 0; int res = 0;
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
switch (bridge->video_mode.mode) { switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE: case AST_BRIDGE_VIDEO_MODE_NONE:
break; break;
case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) { if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc == chan) {
res = 1; res = 1;
} }
break; break;
case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
res = 1; res = 1;
} else if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) { } else if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
res = 2; res = 2;
} }
@@ -5932,30 +5935,30 @@ int ast_bridge_is_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan) void ast_bridge_remove_video_src(struct ast_bridge *bridge, struct ast_channel *chan)
{ {
ast_bridge_lock(bridge); ast_bridge_lock(bridge);
switch (bridge->video_mode.mode) { switch (bridge->softmix.video_mode.mode) {
case AST_BRIDGE_VIDEO_MODE_NONE: case AST_BRIDGE_VIDEO_MODE_NONE:
break; break;
case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC: case AST_BRIDGE_VIDEO_MODE_SINGLE_SRC:
if (bridge->video_mode.mode_data.single_src_data.chan_vsrc == chan) { if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc == chan) {
if (bridge->video_mode.mode_data.single_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.single_src_data.chan_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc);
} }
bridge->video_mode.mode_data.single_src_data.chan_vsrc = NULL; bridge->softmix.video_mode.mode_data.single_src_data.chan_vsrc = NULL;
} }
break; break;
case AST_BRIDGE_VIDEO_MODE_TALKER_SRC: case AST_BRIDGE_VIDEO_MODE_TALKER_SRC:
if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc == chan) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc == chan) {
if (bridge->video_mode.mode_data.talker_src_data.chan_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc);
} }
bridge->video_mode.mode_data.talker_src_data.chan_vsrc = NULL; bridge->softmix.video_mode.mode_data.talker_src_data.chan_vsrc = NULL;
bridge->video_mode.mode_data.talker_src_data.average_talking_energy = 0; bridge->softmix.video_mode.mode_data.talker_src_data.average_talking_energy = 0;
} }
if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc == chan) {
if (bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc) { if (bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc) {
ast_channel_unref(bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc); ast_channel_unref(bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc);
} }
bridge->video_mode.mode_data.talker_src_data.chan_old_vsrc = NULL; bridge->softmix.video_mode.mode_data.talker_src_data.chan_old_vsrc = NULL;
} }
} }
ast_bridge_unlock(bridge); ast_bridge_unlock(bridge);