if (!(data) || !strstr((char *) data, "quiet")) {
conference_utils_member_set_flag(member, MFLAG_INDICATE_MUTE);
}
- member->score_iir = 0;
+ conference_member_set_score_iir(member, 0);
if (stream != NULL) {
stream->write_function(stream, "+OK mute %u\n", member->id);
if (member == NULL)
return SWITCH_STATUS_GENERR;
- switch_mutex_lock(member->conference->mutex);
-
- if (member->conference->floor_holder == member) {
- conference_member_set_floor_holder(member->conference, NULL);
+ if (member->conference->floor_holder == member->id) {
+ conference_member_set_floor_holder(member->conference, NULL, 0);
if (stream != NULL) {
stream->write_function(stream, "+OK floor none\n");
}
- } else if (member->conference->floor_holder == NULL) {
- conference_member_set_floor_holder(member->conference, member);
+ } else if (member->conference->floor_holder == 0) {
+ conference_member_set_floor_holder(member->conference, member, 0);
if (stream != NULL) {
stream->write_function(stream, "+OK floor %u\n", member->id);
}
} else {
if (stream != NULL) {
- stream->write_function(stream, "-ERR floor is held by %u\n", member->conference->floor_holder->id);
+ stream->write_function(stream, "-ERR floor is held by %u\n", member->conference->floor_holder);
}
}
- switch_mutex_unlock(member->conference->mutex);
-
return SWITCH_STATUS_SUCCESS;
}
return SWITCH_STATUS_FALSE;
}
- switch_mutex_lock(member->conference->mutex);
-
if (data && switch_stristr("force", (char *) data)) {
force = 1;
}
if (member->conference->video_floor_holder == member->id && conference_utils_test_flag(member->conference, CFLAG_VID_FLOOR_LOCK)) {
conference_utils_clear_flag(member->conference, CFLAG_VID_FLOOR_LOCK);
- conference_member_set_floor_holder(member->conference, member);
+ conference_member_set_floor_holder(member->conference, member, 0);
if (stream == NULL) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "conference %s OK video floor auto\n", member->conference->name);
} else {
}
}
- switch_mutex_unlock(member->conference->mutex);
-
return SWITCH_STATUS_SUCCESS;
}
if (conference_utils_member_test_flag(other_member, MFLAG_RECEIVING_VIDEO)) {
conference_utils_member_clear_flag(other_member, MFLAG_RECEIVING_VIDEO);
if (conference->floor_holder) {
- switch_core_session_request_video_refresh(conference->floor_holder->session);
+ conference_member_t *omember = NULL;
+
+ if ((omember = conference_member_get(member->conference, conference->floor_holder))) {
+ switch_core_session_request_video_refresh(omember->session);
+ switch_thread_rwlock_unlock(omember->rwlock);
+ }
}
}
switch_thread_rwlock_unlock(other_member->rwlock);
}
conference_utils_member_clear_flag_locked(member, MFLAG_TALKING);
conference_member_update_status_field(member);
- member->score_iir = 0;
+ conference_member_set_score_iir(member, 0);
member->floor_packets = 0;
-
stop_talking_handler(member);
}
}
uint32_t energy = 0, i = 0, samples = 0, j = 0;
int16_t *data;
int gate_check = 0;
-
+ int score_iir = 0;
+
data = read_frame->data;
member->score = 0;
switch_agc_feed(member->agc, (int16_t *)read_frame->data, (read_frame->datalen / 2) * member->conference->channels, 1);
}
- member->score_iir = (int) (((1.0 - SCORE_DECAY) * (float) member->score) + (SCORE_DECAY * (float) member->score_iir));
+ score_iir = (int) (((1.0 - SCORE_DECAY) * (float) member->score) + (SCORE_DECAY * (float) member->score_iir));
- if (member->score_iir > SCORE_MAX_IIR) {
- member->score_iir = SCORE_MAX_IIR;
+ if (score_iir > SCORE_MAX_IIR) {
+ score_iir = SCORE_MAX_IIR;
}
+
+ conference_member_set_score_iir(member, score_iir);
if (member->auto_energy_level && !conference_utils_member_test_flag(member, MFLAG_TALKING)) {
if (++member->auto_energy_track >= (1000 / member->conference->interval * member->conference->auto_energy_sec)) {
hangover_hits--;
}
- if (member == member->conference->floor_holder) {
+ if (member->id == member->conference->floor_holder) {
member->floor_packets++;
}
member->last_score = member->score;
- if (member == member->conference->floor_holder) {
+ if (member->id == member->conference->floor_holder) {
if (member->id != member->conference->video_floor_holder &&
(member->floor_packets > member->conference->video_floor_packets || member->energy_level == 0)) {
conference_video_set_floor_holder(member->conference, member, SWITCH_FALSE);
str = "MUTE";
} else if (switch_channel_test_flag(member->channel, CF_HOLD)) {
str = "HOLD";
- } else if (member == member->conference->floor_holder) {
+ } else if (member->id == member->conference->floor_holder) {
if (conference_utils_member_test_flag(member, MFLAG_TALKING)) {
str = "TALKING (FLOOR)";
} else {
cJSON_AddItemToObject(audio, "deaf", cJSON_CreateBool(!conference_utils_member_test_flag(member, MFLAG_CAN_HEAR)));
cJSON_AddItemToObject(audio, "onHold", cJSON_CreateBool(switch_channel_test_flag(member->channel, CF_HOLD)));
cJSON_AddItemToObject(audio, "talking", cJSON_CreateBool(conference_utils_member_test_flag(member, MFLAG_TALKING)));
- cJSON_AddItemToObject(audio, "floor", cJSON_CreateBool(member == member->conference->floor_holder));
+ cJSON_AddItemToObject(audio, "floor", cJSON_CreateBool(member->id == member->conference->floor_holder));
cJSON_AddItemToObject(audio, "energyScore", cJSON_CreateNumber(member->score));
cJSON_AddItemToObject(json, "audio", audio);
if (member->conference) {
status = conference_event_add_data(member->conference, event);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Floor", "%s", (member == member->conference->floor_holder) ? "true" : "false" );
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Floor", "%s", (member->id == member->conference->floor_holder) ? "true" : "false" );
}
if (member->session) {
return rel;
}
+void conference_member_set_score_iir(conference_member_t *member, uint32_t score)
+{
+ member->score_iir = score;
+ if (member->id == member->conference->floor_holder) {
+ member->conference->floor_holder_score_iir = score;
+ }
+}
+
/* Remove a custom relationship from a member */
switch_status_t conference_member_del_relationship(conference_member_t *member, uint32_t id)
{
member->max_energy_level = conference->max_energy_level;
member->max_energy_hit_trigger = conference->max_energy_hit_trigger;
member->burst_mute_count = conference->burst_mute_count;;
- member->score_iir = 0;
+ conference_member_set_score_iir(member, 0);
member->verbose_events = conference->verbose_events;
member->video_layer_id = -1;
member->layer_timeout = DEFAULT_LAYER_TIMEOUT;
return status;
}
-void conference_member_set_floor_holder(conference_obj_t *conference, conference_member_t *member)
+void conference_member_set_floor_holder(conference_obj_t *conference, conference_member_t *member, uint32_t id)
{
switch_event_t *event;
- conference_member_t *old_member = NULL;
- int old_id = 0;
+ int old_member = 0;
+ uint32_t old_id = 0;
+ conference_member_t *lmember = NULL;
+ conference->floor_holder_score_iir = 0;
+
if (conference->floor_holder) {
- if (conference->floor_holder == member) {
- return;
+ if ((member && conference->floor_holder == member->id) || (id && conference->floor_holder == id)) {
+ goto end;
} else {
old_member = conference->floor_holder;
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %s\n",
- switch_channel_get_name(old_member->channel));
-
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Dropping floor %d\n", old_member);
}
}
- switch_mutex_lock(conference->mutex);
+ if (!member && id) {
+ member = lmember = conference_member_get(conference, id);
+ }
+
+
if (member) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Adding floor %s\n",
switch_channel_get_name(member->channel));
- conference->floor_holder = member;
+ conference->floor_holder = member->id;
+ conference_member_set_score_iir(member, 0);
conference_member_update_status_field(member);
} else {
- conference->floor_holder = NULL;
+ conference->floor_holder = 0;
}
if (old_member) {
- old_id = old_member->id;
- conference_member_update_status_field(old_member);
- old_member->floor_packets = 0;
+ conference_member_t *omember = NULL;
+
+ if ((omember = conference_member_get(conference, old_member))) {
+ old_id = old_member;
+ conference_member_update_status_field(omember);
+ omember->floor_packets = 0;
+ switch_thread_rwlock_unlock(omember->rwlock);
+ }
}
conference_utils_set_flag(conference, CFLAG_FLOOR_CHANGE);
- switch_mutex_unlock(conference->mutex);
if (test_eflag(conference, EFLAG_FLOOR_CHANGE)) {
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT);
}
if (conference->floor_holder) {
- conference_member_add_event_data(conference->floor_holder, event);
- switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder->id);
+ conference_member_add_event_data(member, event);
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-ID", "%d", conference->floor_holder);
} else {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "New-ID", "none");
}
switch_event_fire(&event);
}
+ end:
+
+ if (lmember) {
+ switch_thread_rwlock_unlock(lmember->rwlock);
+ }
}
/* Gain exclusive access and remove the member from the list */
switch_core_speech_close(&member->lsh, &flags);
}
- if (member == member->conference->floor_holder) {
- conference_member_set_floor_holder(member->conference, NULL);
+ if (member->id == member->conference->floor_holder) {
+ conference_member_set_floor_holder(member->conference, NULL, 0);
}
if (member->id == member->conference->video_floor_holder) {
continue;
}
- if (conference->floor_holder && imember == conference->floor_holder) {
+ if (conference->floor_holder && imember->id == conference->floor_holder) {
conference_video_set_floor_holder(conference, imember, 0);
continue;
}
count++;
}
- if (member == member->conference->floor_holder) {
+ if (member->id == member->conference->floor_holder) {
stream->write_function(stream, "%s%s", count ? "|" : "", "floor");
count++;
}
switch_size_t file_data_len = samples * 2 * conference->channels;
int has_file_data = 0, members_with_video = 0, members_with_avatar = 0, members_seeing_video = 0;
int nomoh = 0;
- conference_member_t *floor_holder;
+ uint32_t floor_holder;
switch_status_t moh_status = SWITCH_STATUS_SUCCESS;
/* Sync the conference to a single timing source */
if (conference_utils_member_test_flag(imember, MFLAG_RUNNING) && imember->session) {
switch_channel_t *channel = switch_core_session_get_channel(imember->session);
switch_media_flow_t video_media_flow;
-
- if ((!floor_holder || (imember->score_iir > SCORE_IIR_SPEAKING_MAX && (floor_holder->score_iir < SCORE_IIR_SPEAKING_MIN)))) {// &&
+
+ if ((!floor_holder || (imember->id != conference->floor_holder && imember->score_iir > SCORE_IIR_SPEAKING_MAX && (conference->floor_holder_score_iir < SCORE_IIR_SPEAKING_MIN)))) {// &&
//(!conference_utils_test_flag(conference, CFLAG_VID_FLOOR) || switch_channel_test_flag(channel, CF_VIDEO))) {
- floor_holder = imember;
+
+ conference_member_set_floor_holder(conference, imember, 0);
+ floor_holder = imember->id;
}
video_media_flow = switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO);
conference->members_with_avatar = members_with_avatar;
if (floor_holder != conference->floor_holder) {
- conference_member_set_floor_holder(conference, floor_holder);
+ conference_member_set_floor_holder(conference, NULL, floor_holder);
}
if (conference->moh_wait > 0) {
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_VIDEO_BRIDGE) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "has_floor", count++);
- switch_xml_set_txt_d(x_tag, (member == member->conference->floor_holder) ? "true" : "false");
+ switch_xml_set_txt_d(x_tag, (member->id == member->conference->floor_holder) ? "true" : "false");
x_tag = switch_xml_add_child_d(x_flags, "is_moderator", count++);
switch_xml_set_txt_d(x_tag, conference_utils_member_test_flag(member, MFLAG_MOD) ? "true" : "false");
ADDBOOL(json_conference_member_flags, "talking", conference_utils_member_test_flag(member, MFLAG_TALKING));
ADDBOOL(json_conference_member_flags, "has_video", switch_channel_test_flag(switch_core_session_get_channel(member->session), CF_VIDEO));
ADDBOOL(json_conference_member_flags, "video_bridge", conference_utils_member_test_flag(member, MFLAG_VIDEO_BRIDGE));
- ADDBOOL(json_conference_member_flags, "has_floor", member == member->conference->floor_holder);
+ ADDBOOL(json_conference_member_flags, "has_floor", member->id == member->conference->floor_holder);
ADDBOOL(json_conference_member_flags, "is_moderator", conference_utils_member_test_flag(member, MFLAG_MOD));
ADDBOOL(json_conference_member_flags, "end_conference", conference_utils_member_test_flag(member, MFLAG_ENDCONF));
}
uint32_t channels;
switch_mutex_t *mutex;
conference_member_t *members;
- conference_member_t *floor_holder;
+ uint32_t floor_holder;
uint32_t video_floor_holder;
uint32_t last_video_floor_holder;
switch_mutex_t *member_mutex;
int scale_h264_canvas_fps_divisor;
char *scale_h264_canvas_bandwidth;
uint32_t moh_wait;
+ uint32_t floor_holder_score_iir;
} conference_obj_t;
/* Relationship with another member */
switch_status_t conference_member_parse_position(conference_member_t *member, const char *data);
video_layout_t *conference_video_find_best_layout(conference_obj_t *conference, layout_group_t *lg, uint32_t count, uint32_t file_count);
void conference_list_count_only(conference_obj_t *conference, switch_stream_handle_t *stream);
-void conference_member_set_floor_holder(conference_obj_t *conference, conference_member_t *member);
+void conference_member_set_floor_holder(conference_obj_t *conference, conference_member_t *member, uint32_t id);
void conference_utils_member_clear_flag(conference_member_t *member, member_flag_t flag);
void conference_utils_member_clear_flag_locked(conference_member_t *member, member_flag_t flag);
switch_status_t conference_video_attach_video_layer(conference_member_t *member, mcu_canvas_t *canvas, int idx);
void conference_fnode_toggle_pause(conference_file_node_t *fnode, switch_stream_handle_t *stream);
void conference_fnode_check_status(conference_file_node_t *fnode, switch_stream_handle_t *stream);
-
+void conference_member_set_score_iir(conference_member_t *member, uint32_t score);
// static conference_relationship_t *conference_member_get_relationship(conference_member_t *member, conference_member_t *other_member);
// static void conference_list(conference_obj_t *conference, switch_stream_handle_t *stream, char *delim);