From 2b5b9341e7e0ed1f8c7e7abbeec7de7d96ef4d36 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 21 Nov 2017 17:21:21 -0600 Subject: [PATCH] FS-10802: [mod_conference] Convert conference floor to id based #resolve --- .../mod_conference/conference_api.c | 29 ++++---- .../mod_conference/conference_loop.c | 18 ++--- .../mod_conference/conference_member.c | 69 ++++++++++++------- .../mod_conference/conference_video.c | 2 +- .../mod_conference/mod_conference.c | 18 ++--- .../mod_conference/mod_conference.h | 7 +- 6 files changed, 84 insertions(+), 59 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_api.c b/src/mod/applications/mod_conference/conference_api.c index 034763dd00..c8fa1eca6c 100644 --- a/src/mod/applications/mod_conference/conference_api.c +++ b/src/mod/applications/mod_conference/conference_api.c @@ -321,7 +321,7 @@ switch_status_t conference_api_sub_mute(conference_member_t *member, switch_stre 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); @@ -2046,26 +2046,22 @@ switch_status_t conference_api_sub_floor(conference_member_t *member, switch_str 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; } @@ -2356,8 +2352,6 @@ switch_status_t conference_api_sub_vid_floor(conference_member_t *member, switch return SWITCH_STATUS_FALSE; } - switch_mutex_lock(member->conference->mutex); - if (data && switch_stristr("force", (char *) data)) { force = 1; } @@ -2365,7 +2359,7 @@ switch_status_t conference_api_sub_vid_floor(conference_member_t *member, switch 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 { @@ -2392,8 +2386,6 @@ switch_status_t conference_api_sub_vid_floor(conference_member_t *member, switch } } - switch_mutex_unlock(member->conference->mutex); - return SWITCH_STATUS_SUCCESS; } @@ -2911,7 +2903,12 @@ void _conference_api_sub_relate_clear_member_relationship(conference_obj_t *conf 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); diff --git a/src/mod/applications/mod_conference/conference_loop.c b/src/mod/applications/mod_conference/conference_loop.c index 301f09d090..5c6947252b 100644 --- a/src/mod/applications/mod_conference/conference_loop.c +++ b/src/mod/applications/mod_conference/conference_loop.c @@ -910,9 +910,8 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob } 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); } } @@ -926,7 +925,8 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob 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; @@ -953,11 +953,13 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob 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)) { @@ -1091,7 +1093,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob hangover_hits--; } - if (member == member->conference->floor_holder) { + if (member->id == member->conference->floor_holder) { member->floor_packets++; } @@ -1164,7 +1166,7 @@ void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, void *ob 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); diff --git a/src/mod/applications/mod_conference/conference_member.c b/src/mod/applications/mod_conference/conference_member.c index c29aa41098..f971134119 100644 --- a/src/mod/applications/mod_conference/conference_member.c +++ b/src/mod/applications/mod_conference/conference_member.c @@ -137,7 +137,7 @@ void conference_member_update_status_field(conference_member_t *member) 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 { @@ -169,7 +169,7 @@ void conference_member_update_status_field(conference_member_t *member) 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); @@ -237,7 +237,7 @@ switch_status_t conference_member_add_event_data(conference_member_t *member, sw 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) { @@ -629,6 +629,14 @@ conference_relationship_t *conference_member_add_relationship(conference_member_ 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) { @@ -703,7 +711,7 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m 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; @@ -1049,43 +1057,53 @@ switch_status_t conference_member_add(conference_obj_t *conference, conference_m 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); @@ -1098,8 +1116,8 @@ void conference_member_set_floor_holder(conference_obj_t *conference, conference } 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"); } @@ -1107,6 +1125,11 @@ void conference_member_set_floor_holder(conference_obj_t *conference, conference switch_event_fire(&event); } + end: + + if (lmember) { + switch_thread_rwlock_unlock(lmember->rwlock); + } } /* Gain exclusive access and remove the member from the list */ @@ -1224,8 +1247,8 @@ switch_status_t conference_member_del(conference_obj_t *conference, conference_m 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) { diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 9479152ec8..97ae8d1d6e 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -4481,7 +4481,7 @@ void conference_video_find_floor(conference_member_t *member, switch_bool_t ente 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; } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 0ac4c255d1..95fdfc03ac 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -117,7 +117,7 @@ void conference_list(conference_obj_t *conference, switch_stream_handle_t *strea count++; } - if (member == member->conference->floor_holder) { + if (member->id == member->conference->floor_holder) { stream->write_function(stream, "%s%s", count ? "|" : "", "floor"); count++; } @@ -242,7 +242,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob 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 */ @@ -301,10 +301,12 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob 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); @@ -364,7 +366,7 @@ void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, void *ob 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) { @@ -1271,7 +1273,7 @@ void conference_xlist(conference_obj_t *conference, switch_xml_t x_conference, i 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"); @@ -1376,7 +1378,7 @@ void conference_jlist(conference_obj_t *conference, cJSON *json_conferences) 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)); } diff --git a/src/mod/applications/mod_conference/mod_conference.h b/src/mod/applications/mod_conference/mod_conference.h index c7ae4bf3cc..ff15c7329e 100644 --- a/src/mod/applications/mod_conference/mod_conference.h +++ b/src/mod/applications/mod_conference/mod_conference.h @@ -673,7 +673,7 @@ typedef struct conference_obj { 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; @@ -754,6 +754,7 @@ typedef struct conference_obj { 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 */ @@ -1025,7 +1026,7 @@ al_handle_t *conference_al_create(switch_memory_pool_t *pool); 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); @@ -1084,7 +1085,7 @@ void conference_member_check_channels(switch_frame_t *frame, conference_member_t 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);