]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
add a way to tell mod_conference when the rate of the channel has changed due to...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Mar 2014 00:17:47 +0000 (05:17 +0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 7 Mar 2014 00:17:47 +0000 (05:17 +0500)
src/include/switch_types.h
src/mod/applications/mod_conference/mod_conference.c
src/switch_core_io.c
src/switch_core_media.c
src/switch_core_session.c

index 9dfe04b5eba6d93d892067be7ba6730e87850c2a..338b4c495651f6d63fff178a825d696ebe3f013d 100644 (file)
@@ -1013,6 +1013,7 @@ typedef enum {
        SWITCH_MESSAGE_ANSWER_EVENT,
        SWITCH_MESSAGE_PROGRESS_EVENT,
        SWITCH_MESSAGE_RING_EVENT,
+       SWITCH_MESSAGE_RESAMPLE_EVENT,
        SWITCH_MESSAGE_INVALID
 } switch_core_session_message_types_t;
 
@@ -1407,6 +1408,7 @@ typedef enum {
        CF_VIDEO_PAUSE,
        CF_BYPASS_MEDIA_AFTER_HOLD,
        CF_HANGUP_HELD,
+       CF_CONFERENCE_RESET_MEDIA,
        /* WARNING: DO NOT ADD ANY FLAGS BELOW THIS LINE */
        /* IF YOU ADD NEW ONES CHECK IF THEY SHOULD PERSIST OR ZERO THEM IN switch_core_session.c switch_core_session_request_xml() */
        CF_FLAG_MAX
index 9c6c2419d93546c639db5ce4afacd739a6287485..4e67b99041d7866c7ce8d23e819610409544b0d1 100644 (file)
@@ -485,6 +485,7 @@ struct conference_member {
        switch_thread_t *input_thread;
        cJSON *json;
        cJSON *status_field;
+       uint8_t loop_loop;
 };
 
 typedef enum {
@@ -3659,7 +3660,7 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
        switch_frame_t *read_frame = NULL;
        uint32_t hangover = 40, hangunder = 5, hangover_hits = 0, hangunder_hits = 0, diff_level = 400;
        switch_core_session_t *session = member->session;
-       uint32_t flush_len;
+       uint32_t flush_len, loops = 0;
 
        if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) {
                goto end;
@@ -3922,6 +3923,18 @@ static void *SWITCH_THREAD_FUNC conference_loop_input(switch_thread_t *thread, v
                        member->last_score = member->score;
                }
 
+               if (switch_channel_test_flag(member->channel, CF_CONFERENCE_RESET_MEDIA)) {
+                       switch_channel_clear_flag(member->channel, CF_CONFERENCE_RESET_MEDIA);
+                       if (++loops > 500) {
+                               member->loop_loop = 1;
+
+                               if (setup_media(member, member->conference)) {
+                                       break;
+                               }
+                       }
+
+               }
+
                /* skip frames that are not actual media or when we are muted or silent */
                if ((switch_test_flag(member, MFLAG_TALKING) || member->energy_level == 0 || switch_test_flag(member->conference, CFLAG_AUDIO_ALWAYS)) 
                        && switch_test_flag(member, MFLAG_CAN_SPEAK) && !switch_test_flag(member->conference, CFLAG_WAIT_MOD)
@@ -4072,7 +4085,7 @@ static void launch_conference_loop_input(conference_member_t *member, switch_mem
 {
        switch_threadattr_t *thd_attr = NULL;
 
-       if (member == NULL)
+       if (member == NULL || member->input_thread)
                return;
 
        switch_threadattr_create(&thd_attr, pool);
@@ -4116,7 +4129,7 @@ static void conference_loop_output(conference_member_t *member)
        call_list = NULL;
        cp = NULL;
 
-
+       member->loop_loop = 0;
 
        switch_assert(member->conference != NULL);
 
@@ -4229,7 +4242,7 @@ static void conference_loop_output(conference_member_t *member)
 
        /* Fair WARNING, If you expect the caller to hear anything or for digit handling to be processed,      */
        /* you better not block this thread loop for more than the duration of member->conference->timer_name!  */
-       while (switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
+       while (!member->loop_loop && switch_test_flag(member, MFLAG_RUNNING) && switch_test_flag(member, MFLAG_ITHREAD)
                   && switch_channel_ready(channel)) {
                switch_event_t *event;
                int use_timer = 0;
@@ -4429,15 +4442,21 @@ static void conference_loop_output(conference_member_t *member)
 
  end:
 
-       switch_clear_flag_locked(member, MFLAG_RUNNING);
+       if (!member->loop_loop) {
+               switch_clear_flag_locked(member, MFLAG_RUNNING);
 
-       /* Wait for the input thread to end */
-       if (member->input_thread) {
-               switch_thread_join(&st, member->input_thread);
+               /* Wait for the input thread to end */
+               if (member->input_thread) {
+                       switch_thread_join(&st, member->input_thread);
+               }
        }
 
        switch_core_timer_destroy(&timer);
 
+       if (member->loop_loop) {
+               return;
+       }
+
        switch_log_printf(SWITCH_CHANNEL_CHANNEL_LOG(channel), SWITCH_LOG_DEBUG, "Channel leaving conference, cause: %s\n",
                                          switch_channel_cause2str(switch_channel_get_cause(channel)));
 
@@ -8006,10 +8025,14 @@ static int setup_media(conference_member_t *member, conference_obj_t *conference
        switch_codec_implementation_t read_impl = { 0 };
        switch_core_session_get_read_impl(member->session, &read_impl);
 
-       switch_core_session_reset(member->session, SWITCH_TRUE, SWITCH_FALSE);
-
        if (switch_core_codec_ready(&member->read_codec)) {
                switch_core_codec_destroy(&member->read_codec);
+               memset(&member->read_codec, 0, sizeof(&member->read_codec));
+       }
+
+       if (switch_core_codec_ready(&member->write_codec)) {
+               switch_core_codec_destroy(&member->write_codec);
+               memset(&member->write_codec, 0, sizeof(&member->write_codec));
        }
 
        if (member->read_resampler) {
@@ -8640,7 +8663,10 @@ SWITCH_STANDARD_APP(conference_function)
        switch_core_session_receive_message(session, &msg);
 
        /* Run the conference loop */
-       conference_loop_output(&member);
+       do {
+               conference_loop_output(&member);
+       } while (member.loop_loop);
+
        switch_channel_set_private(channel, "_conference_autocall_list_", NULL);
 
        /* Tell the channel we are no longer going to be in a bridge */
index c290d9175fba4affa95b8c94369686fa63a58959..4c7b7fd8b802976851d7a707ea99d1a6aa18c36c 100644 (file)
@@ -599,6 +599,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
                        case SWITCH_STATUS_RESAMPLE:
                                if (!session->read_resampler) {
                                        switch_mutex_lock(session->resample_mutex);
+
                                        status = switch_resample_create(&session->read_resampler,
                                                                                                        read_frame->codec->implementation->actual_samples_per_second,
                                                                                                        session->read_impl.actual_samples_per_second,
@@ -610,6 +611,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
                                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Unable to allocate resampler\n");
                                                status = SWITCH_STATUS_FALSE;
                                                goto done;
+                                       } else {
+                                               switch_core_session_message_t msg = { 0 };
+                                               msg.numeric_arg = 1;
+                                               msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                               switch_core_session_receive_message(session, &msg);
+
+                                               switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating read resampler\n");
                                        }
                                }
                        case SWITCH_STATUS_SUCCESS:
@@ -636,6 +644,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
                                        switch_resample_destroy(&session->read_resampler);
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating read resampler\n");
                                        switch_mutex_unlock(session->resample_mutex);
+
+                                       {
+                                               switch_core_session_message_t msg = { 0 };
+                                               msg.numeric_arg = 0;
+                                               msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                               switch_core_session_receive_message(session, &msg);
+                                       }
+
                                }
 
                                status = SWITCH_STATUS_SUCCESS;
@@ -1199,6 +1215,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                                switch_mutex_unlock(session->resample_mutex);
                                if (status != SWITCH_STATUS_SUCCESS) {
                                        goto done;
+                               } else {
+                                       switch_core_session_message_t msg = { 0 };
+                                       msg.numeric_arg = 1;
+                                       msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                       switch_core_session_receive_message(session, &msg);
+
+                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
                                }
                        }
                        break;
@@ -1226,6 +1249,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                                switch_resample_destroy(&session->write_resampler);
                                switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
                                switch_mutex_unlock(session->resample_mutex);
+
+                               {
+                                       switch_core_session_message_t msg = { 0 };
+                                       msg.numeric_arg = 0;
+                                       msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                       switch_core_session_receive_message(session, &msg);
+                               }
+
                        }
                        write_frame = frame;
                        status = SWITCH_STATUS_SUCCESS;
@@ -1497,6 +1528,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
 
                                                if (status != SWITCH_STATUS_SUCCESS) {
                                                        goto done;
+                                               } else {
+                                                       switch_core_session_message_t msg = { 0 };
+                                                       msg.numeric_arg = 1;
+                                                       msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                                       switch_core_session_receive_message(session, &msg);
+                                                       
+
+                                                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Activating write resampler\n");
                                                }
                                        }
                                        break;
@@ -1511,12 +1550,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                                        break;
                                case SWITCH_STATUS_NOOP:
                                        if (session->write_resampler) {
+                                               switch_core_session_message_t msg = { 0 };
+                                               int ok = 0;
+
                                                switch_mutex_lock(session->resample_mutex);
-                                               if (session->write_resampler) {
+                                               if (session->write_resampler) {                                 
                                                        switch_resample_destroy(&session->write_resampler);
                                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_NOTICE, "Deactivating write resampler\n");
+                                                       ok = 1;
                                                }
                                                switch_mutex_unlock(session->resample_mutex);
+
+                                               if (ok) {
+                                                       msg.numeric_arg = 0;
+                                                       msg.message_id = SWITCH_MESSAGE_RESAMPLE_EVENT;
+                                                       switch_core_session_receive_message(session, &msg);
+                                               }
+
                                        }
                                        enc_frame->codec = session->write_codec;
                                        enc_frame->samples = enc_frame->datalen / sizeof(int16_t);
index db6d6497af4203038bf79a519f20659f2e547383..0b8b66747c0ed2e6fa4ab6331e25fdd82032a964 100644 (file)
@@ -7479,6 +7479,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se
 
        switch (msg->message_id) {
 
+       case SWITCH_MESSAGE_RESAMPLE_EVENT:
+               {
+                       if (switch_channel_test_flag(session->channel, CF_CONFERENCE)) {
+                               switch_channel_set_flag(session->channel, CF_CONFERENCE_RESET_MEDIA);
+                       }
+               }
+               break;
+
        case SWITCH_MESSAGE_INDICATE_VIDEO_REFRESH_REQ:
                {
                        if (v_engine->rtp_session) {
index 028f74545730e2c4d2fd4162df1b44b16916cbf1..03b57fd788bb84ca7b8db132f6e7ba57016110df 100644 (file)
@@ -754,6 +754,7 @@ static const char *message_names[] = {
        "ANSWER_EVENT",
        "PROGRESS_EVENT",
        "RING_EVENT",
+       "RESAMPLE_EVENT",
        "INVALID"
 };