]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-10802: [mod_conference] Convert conference floor to id based #resolve
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 21 Nov 2017 23:21:21 +0000 (17:21 -0600)
committerMuteesa Fred <muteesafred@hotmail.com>
Tue, 24 Jul 2018 07:21:36 +0000 (07:21 +0000)
src/mod/applications/mod_conference/conference_api.c
src/mod/applications/mod_conference/conference_loop.c
src/mod/applications/mod_conference/conference_member.c
src/mod/applications/mod_conference/conference_video.c
src/mod/applications/mod_conference/mod_conference.c
src/mod/applications/mod_conference/mod_conference.h

index 034763dd00ee0bea9ef90c8a65f859d2b7dad606..c8fa1eca6c17d3d0329405b261515e53262a3040 100644 (file)
@@ -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);
index 301f09d090358fd6384959e0c28c82caa2267531..5c6947252b960d7710a5f3880a6c5bedea7b789e 100644 (file)
@@ -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);
index c29aa41098a323e287d3cfb132c20a3bd3b4c29f..f971134119bb95e5a6bc27d271b005ecc7abf744 100644 (file)
@@ -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) {
index 9479152ec8ab4f1fcc6da346a9eed18595cd26e2..97ae8d1d6edf2f4a1cd2ec0501887c56e2b67dcc 100644 (file)
@@ -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;
                }
index 0ac4c255d18c4725821a3f9321219fe03ebda887..95fdfc03aca02b58c6adf3821cd260e0f752996e 100644 (file)
@@ -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));
        }
index c7ae4bf3cca3710b8bc95339259295ad71b4a08d..ff15c7329e25a43708693de30102318067c53b75 100644 (file)
@@ -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);