]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-3816 --resolve
authorAnthony Minessale <anthm@freeswitch.org>
Tue, 17 Jan 2012 15:43:14 +0000 (09:43 -0600)
committerAnthony Minessale <anthm@freeswitch.org>
Tue, 17 Jan 2012 15:43:14 +0000 (09:43 -0600)
src/include/switch_core.h
src/mod/endpoints/mod_sofia/sofia_glue.c
src/switch_core_codec.c

index b42e028ec0724f95bcdd28feec869475814e8bdc..c76eeabb0fd4112b6d18354e5d3f7153685ed041 100644 (file)
@@ -1467,6 +1467,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_codec_destroy(switch_codec_t *codec)
 */
 SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec);
 
+/*! 
+  \brief Assign the original read codec to a given session.  This is the read codec used by an endpoint.
+  \param session session to add the codec to
+  \param codec the codec to add
+  \return SWITCH_STATUS_SUCCESS if successful
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(_In_ switch_core_session_t *session, switch_codec_t *codec);
+
 SWITCH_DECLARE(void) switch_core_session_unset_read_codec(_In_ switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_session_unset_write_codec(_In_ switch_core_session_t *session);
 
index d714c23a00c0727c8c6bb0556bbf877a56d0cdcc..d685091e6b4b75be9669c22e349cadf10a06cee2 100644 (file)
@@ -2925,7 +2925,7 @@ switch_status_t sofia_glue_tech_set_codec(private_object_t *tech_pvt, int force)
        tech_pvt->read_codec.agreed_pt = tech_pvt->agreed_pt;
 
        if (force != 2) {
-               switch_core_session_set_read_codec(tech_pvt->session, &tech_pvt->read_codec);
+               switch_core_session_set_real_read_codec(tech_pvt->session, &tech_pvt->read_codec);
                switch_core_session_set_write_codec(tech_pvt->session, &tech_pvt->write_codec);
        }
 
index feaca4b7ed2077763b55ace8050487cc9ba0abe5..52bf1c274f47e2c81280a20868fc404c8d379702 100644 (file)
@@ -26,6 +26,7 @@
  * Anthony Minessale II <anthm@freeswitch.org>
  * Michael Jerris <mike@jerris.com>
  * Paul D. Tinsley <pdt at jackhammer.org>
+ * Chris Rienzo <chris@rienzo.net>
  *
  *
  * switch_core_codec.c -- Main Core Library (codec functions)
@@ -90,6 +91,96 @@ SWITCH_DECLARE(void) switch_core_session_unset_write_codec(switch_core_session_t
        switch_mutex_unlock(session->codec_write_mutex);
 }
 
+SWITCH_DECLARE(switch_status_t) switch_core_session_set_real_read_codec(switch_core_session_t *session, switch_codec_t *codec)
+{
+       switch_event_t *event;
+       switch_channel_t *channel = switch_core_session_get_channel(session);
+       char tmp[30];
+       switch_status_t status = SWITCH_STATUS_SUCCESS;
+       int changed_read_codec = 0;
+
+       switch_mutex_lock(session->codec_read_mutex);
+
+       if (codec && (!codec->implementation || !switch_core_codec_ready(codec))) {
+               codec = NULL;
+       }
+
+       if (codec) {
+               /* set real_read_codec and read_codec */
+               if (!session->real_read_codec) {
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Original read codec set to %s:%d\n",
+                                                         switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode);
+                       session->read_codec = session->real_read_codec = codec;
+                       if (codec->implementation) {
+                               session->read_impl = *codec->implementation;
+                       } else {
+                               memset(&session->read_impl, 0, sizeof(session->read_impl));
+                       }
+               } else { /* replace real_read_codec */
+                       switch_codec_t *cur_codec;
+                       if (session->real_read_codec == session->read_codec) {
+                               goto end;
+                       }
+                       switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s Original read codec replaced with %s:%d\n",
+                                                         switch_channel_get_name(session->channel), codec->implementation->iananame, codec->implementation->ianacode);
+                       /* Set real_read_codec to front of the list of read_codecs */
+                       cur_codec = session->read_codec;
+                       changed_read_codec = 1;
+                       while (cur_codec != NULL) {
+                               if (cur_codec->next == session->real_read_codec) {
+                                       cur_codec->next = codec;
+                                       break;
+                               }
+                               cur_codec = cur_codec->next;
+                       }
+                       session->real_read_codec = codec;
+                       /* set read_codec with real_read_codec if it no longer is ready */
+                       if (!switch_core_codec_ready(session->read_codec)) {
+                               session->read_codec = codec;
+                               changed_read_codec = 1;
+                               if (codec->implementation) {
+                               session->read_impl = *codec->implementation;
+                               } else {
+                                       memset(&session->read_impl, 0, sizeof(session->read_impl));
+                               }
+                       }
+               }
+       } else {
+               status = SWITCH_STATUS_FALSE;
+               goto end;
+       }
+
+       if (changed_read_codec && session->read_codec && session->read_impl.decoded_bytes_per_packet) {
+               if (switch_event_create(&event, SWITCH_EVENT_CODEC) == SWITCH_STATUS_SUCCESS) {
+                       switch_channel_event_set_data(session->channel, event);
+                       switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "channel-read-codec-name", session->read_impl.iananame);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-rate", "%d", session->read_impl.actual_samples_per_second);
+                       switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-read-codec-bit-rate", "%d", session->read_impl.bits_per_second);
+                       if (session->read_impl.actual_samples_per_second != session->read_impl.samples_per_second) {
+                               switch_event_add_header(event, SWITCH_STACK_BOTTOM, "channel-reported-read-codec-rate", "%d", session->read_impl.samples_per_second);
+                       }
+                       switch_event_fire(&event);
+               }
+
+               switch_channel_set_variable(channel, "read_codec", session->read_impl.iananame);
+               switch_snprintf(tmp, sizeof(tmp), "%d", session->read_impl.actual_samples_per_second);
+               switch_channel_set_variable(channel, "read_rate", tmp);
+
+               session->raw_read_frame.codec = session->read_codec;
+               session->raw_write_frame.codec = session->read_codec;
+               session->enc_read_frame.codec = session->read_codec;
+               session->enc_write_frame.codec = session->read_codec;
+       }
+
+  end:
+
+       if (session->read_codec) {
+               switch_channel_set_flag(channel, CF_MEDIA_SET);
+       }
+
+       switch_mutex_unlock(session->codec_read_mutex);
+       return status;
+}
 
 SWITCH_DECLARE(switch_status_t) switch_core_session_set_read_codec(switch_core_session_t *session, switch_codec_t *codec)
 {