]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
make a way to get the jitter buffer down to the codecs
authorAnthony Minessale <anthm@freeswitch.org>
Thu, 18 Oct 2012 19:29:00 +0000 (15:29 -0400)
committerAnthony Minessale <anthm@freeswitch.org>
Thu, 18 Oct 2012 19:29:00 +0000 (15:29 -0400)
14 files changed:
libs/stfu/stfu.c
libs/stfu/stfu.h
src/include/switch.h
src/include/switch_core.h
src/include/switch_frame.h
src/include/switch_module_interfaces.h
src/include/switch_rtp.h
src/include/switch_types.h
src/mod/codecs/mod_silk/mod_silk.c
src/mod/endpoints/mod_sofia/mod_sofia.c
src/switch_core_io.c
src/switch_core_session.c
src/switch_ivr.c
src/switch_rtp.c

index 787fd9c3d9f2fdb0eb45c7f7b72497e5a4dba191..7ca036fc64e03eda6760b8b5abb147e9510d690c 100644 (file)
@@ -402,7 +402,7 @@ static void stfu_n_swap(stfu_instance_t *i)
     i->out_queue->last_jitter = 0;
 }
 
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last)
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last)
 {
        uint32_t index = 0;
        stfu_frame_t *frame;
@@ -569,6 +569,7 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
 
     frame->pt = pt;
        frame->ts = ts;
+    frame->seq = seq;
        frame->dlen = cplen;
        frame->was_read = 0;    
 
index 045b6440095a00a0eee729ea99320c50121ae2bb..e3d05bcbc126f85b317317a7cb38c3b6ac39d3c8 100644 (file)
@@ -163,6 +163,7 @@ typedef enum {
 
 struct stfu_frame {
        uint32_t ts;
+       uint16_t seq;
        uint32_t pt;
        uint8_t data[STFU_DATALEN];
        size_t dlen;
@@ -188,7 +189,7 @@ void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
 void stfu_n_destroy(stfu_instance_t **i);
 stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_per_packet, uint32_t samples_per_second, uint32_t max_drift_ms);
 stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
-stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last);
+stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last);
 stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
 void stfu_n_reset(stfu_instance_t *i);
 stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
@@ -197,8 +198,8 @@ void stfu_n_debug(stfu_instance_t *i, const char *name);
 int32_t stfu_n_get_drift(stfu_instance_t *i);
 int32_t stfu_n_get_most_qlen(stfu_instance_t *i);
 
-#define stfu_im_done(i) stfu_n_add_data(i, 0, NULL, 0, 0, 1)
-#define stfu_n_eat(i,t,p,d,l,tt) stfu_n_add_data(i, t, p, d, l, tt, 0)
+#define stfu_im_done(i) stfu_n_add_data(i, 0, 0, NULL, 0, 0, 1)
+#define stfu_n_eat(i,t,s,p,d,l,tt) stfu_n_add_data(i, t, s, p, d, l, tt, 0)
 
 #ifdef __cplusplus
 }
index 1eb45ae48a9536bf4c023cf67222d08d0ab5dee8..3cfa271be4b070af47156d947658ee983e925e67 100644 (file)
 #include <signal.h>
 #include <errno.h>
 
+#include "../../../libs/stfu/stfu.h"
 #include "switch_platform.h"
 #include "switch_types.h"
 #include "switch_apr.h"
 #include "switch_pgsql.h"
 #include "switch_json.h"
 #include "switch_limit.h"
-
 #include <libteletone.h>
 
+
 /** \mainpage FreeSWITCH
  * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
 
index 3cb4dc81167ddaaed9d488a0bc3f9e4b8fe2664c..a3898d9d64c8911fb185c653014a0082511fcf93 100644 (file)
@@ -741,7 +741,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_set_loglevel(switch_core_ses
 */
 SWITCH_DECLARE(switch_log_level_t) switch_core_session_get_loglevel(switch_core_session_t *session);
                                                                   
-
+SWITCH_DECLARE(stfu_instance_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type);
 SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec);
 SWITCH_DECLARE(void) switch_core_session_soft_unlock(switch_core_session_t *session);
 SWITCH_DECLARE(void) switch_core_session_set_dmachine(switch_core_session_t *session, switch_ivr_dmachine_t *dmachine, switch_digit_action_target_t target);
index 91910f85ddbb25b933e0ab5c077597de0f50a177..812aa5d4132611e67ac4b00ae9b91dc48ef7aba9 100644 (file)
@@ -70,6 +70,7 @@ SWITCH_BEGIN_EXTERN_C
        switch_bool_t m;
        /*! frame flags */
        switch_frame_flag_t flags;
+       void *user_data;
 };
 
 SWITCH_END_EXTERN_C
index e92e1a136629c5542f502050efb890927b347d3b..deb96e4d47dcbd320c840fde190f8eabbd997946 100644 (file)
@@ -118,6 +118,7 @@ typedef switch_status_t (*switch_io_state_change_t) (switch_core_session_t *);
 typedef switch_status_t (*switch_io_state_run_t) (switch_core_session_t *);
 typedef switch_status_t (*switch_io_read_video_frame_t) (switch_core_session_t *, switch_frame_t **, switch_io_flag_t, int);
 typedef switch_status_t (*switch_io_write_video_frame_t) (switch_core_session_t *, switch_frame_t *, switch_io_flag_t, int);
+typedef stfu_instance_t *(*switch_io_get_jb_t) (switch_core_session_t *, switch_media_type_t);
 
 typedef enum {
        SWITCH_IO_OUTGOING_CHANNEL,
@@ -130,6 +131,7 @@ typedef enum {
        SWITCH_IO_STATE_CHANGE,
        SWITCH_IO_READ_VIDEO_FRAME,
        SWITCH_IO_WRITE_VIDEO_FRAME,
+       SWITCH_IO_GET_JB,
 } switch_io_routine_name_t;
 
 /*! \brief A table of i/o routines that an endpoint interface can implement */
@@ -156,6 +158,8 @@ struct switch_io_routines {
        switch_io_write_video_frame_t write_video_frame;
        /*! change a sessions channel run state */
        switch_io_state_run_t state_run;
+       /*! get sessions jitterbuffer */
+       switch_io_get_jb_t get_jb;
        void *padding[10];
 };
 
@@ -613,6 +617,7 @@ struct switch_codec {
        switch_payload_t agreed_pt;
        switch_mutex_t *mutex;
        struct switch_codec *next;
+       switch_core_session_t *session;
 };
 
 /*! \brief A table of settings and callbacks that define a paticular implementation of a codec */
index 602889f3d6ab200782ae2905692048b2eb69201d..0a4ac93643822e8e0eab95fcd10b85b0d3774639 100644 (file)
@@ -240,6 +240,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_debug_jitter_buffer(switch_rtp_t *rtp
 
 SWITCH_DECLARE(switch_status_t) switch_rtp_deactivate_jitter_buffer(switch_rtp_t *rtp_session);
 SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause);
+SWITCH_DECLARE(stfu_instance_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session);
 
 /*!
   \brief Set an RTP Flag
index f1c5f1b65a8c8eeb2937ffedc4a6c1e7c14af17a..c4c2ed7190f23a4b1f75508bdbd3cf80536976dd 100644 (file)
@@ -1427,6 +1427,11 @@ typedef enum {
        SWITCH_CODEC_TYPE_APP
 } switch_codec_type_t;
 
+typedef enum {
+       SWITCH_MEDIA_TYPE_AUDIO,
+       SWITCH_MEDIA_TYPE_VIDEO
+} switch_media_type_t;
+
 
 /*!
   \enum switch_timer_flag_t
index 5c32b72969c95cba4bf16f41f8025440c6b1e2f1..af32332de2a99bab39944029dc70f237d2c8ed42 100644 (file)
@@ -320,9 +320,20 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec,
        struct silk_context *context = codec->private_info;
        SKP_int16 ret, len; 
        int16_t *target = decoded_data;
+       switch_core_session_t *session = codec->session;
+       stfu_instance_t *jb;
 
        *decoded_data_len = 0;
 
+       if (session) {
+               jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
+       }
+
+       if (jb) {
+               /* to allow compile */
+               jb = NULL;
+       }
+
        do {
                ret = SKP_Silk_SDK_Decode(context->dec_state,
                                                                  &context->decoder_object,
index 3f26a26fff7f2223e2944fc4c1a080f4a1f79284..20bff868de2080063b3113e5a53401948f300ba7 100644 (file)
@@ -306,6 +306,24 @@ char *generate_pai_str(private_object_t *tech_pvt)
        return pai;
 }
 
+static stfu_instance_t *sofia_get_jb(switch_core_session_t *session, switch_media_type_t type)
+{
+       private_object_t *tech_pvt = (private_object_t *) switch_core_session_get_private(session);
+       switch_rtp_t *rtp;
+       
+       if (type == SWITCH_MEDIA_TYPE_AUDIO) {
+               rtp = tech_pvt->rtp_session;
+       } else {
+               rtp = tech_pvt->video_rtp_session;
+       }
+
+       if (rtp && switch_rtp_ready(rtp)) {
+               return switch_rtp_get_jitter_buffer(rtp);
+       }
+       
+       return NULL;
+}
+
 /* map QSIG cause codes to SIP from RFC4497 section 8.4.1 */
 static int hangup_cause_to_sip(switch_call_cause_t cause)
 {
@@ -4501,7 +4519,9 @@ switch_io_routines_t sofia_io_routines = {
        /*.receive_event */ sofia_receive_event,
        /*.state_change */ NULL,
        /*.read_video_frame */ sofia_read_video_frame,
-       /*.write_video_frame */ sofia_write_video_frame
+       /*.write_video_frame */ sofia_write_video_frame,
+       /*.state_run*/ NULL,
+       /*.get_jb*/ sofia_get_jb
 };
 
 switch_state_handler_table_t sofia_event_handlers = {
index 7b9580c0bbd79f1cd4c774576962e78b3982436a..7dbfdb2ac8161ea527266519bba1f38df6f01e86 100644 (file)
@@ -373,14 +373,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
                                        memset(session->raw_read_frame.data, 255, session->raw_read_frame.datalen);
                                        status = SWITCH_STATUS_SUCCESS;
                                } else {
+                                       switch_codec_t *codec = use_codec->implementation?use_codec:read_frame->codec;
                                        switch_thread_rwlock_rdlock(session->bug_rwlock);
-                                       status = switch_core_codec_decode(use_codec->implementation?use_codec:read_frame->codec,
+                                       codec->session = session;
+                                       status = switch_core_codec_decode(codec,
                                                                                                          session->read_codec,
                                                                                                          read_frame->data,
                                                                                                          read_frame->datalen,
                                                                                                          session->read_impl.actual_samples_per_second,
                                                                                                          session->raw_read_frame.data, &session->raw_read_frame.datalen, &session->raw_read_frame.rate, 
                                                                                                          &read_frame->flags);
+                                       codec->session = NULL;
                                        switch_thread_rwlock_unlock(session->bug_rwlock);
 
                                }
@@ -623,14 +626,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi
                                switch_assert(session->read_codec != NULL);
                                switch_assert(enc_frame != NULL);
                                switch_assert(enc_frame->data != NULL);
-
+                               session->read_codec->session = session;
                                status = switch_core_codec_encode(session->read_codec,
                                                                                                  enc_frame->codec,
                                                                                                  enc_frame->data,
                                                                                                  enc_frame->datalen,
                                                                                                  session->read_impl.actual_samples_per_second,
                                                                                                  session->enc_read_frame.data, &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag);
-
+                               session->read_codec->session = NULL;
                                switch (status) {
                                case SWITCH_STATUS_RESAMPLE:
                                        switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Fixme 1\n");
@@ -904,12 +907,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
 
        if (frame->codec) {
                session->raw_write_frame.datalen = session->raw_write_frame.buflen;
+               frame->codec->session = session;
                status = switch_core_codec_decode(frame->codec,
                                                                                  session->write_codec,
                                                                                  frame->data,
                                                                                  frame->datalen,
                                                                                  session->write_impl.actual_samples_per_second,
                                                                                  session->raw_write_frame.data, &session->raw_write_frame.datalen, &session->raw_write_frame.rate, &frame->flags);
+               frame->codec->session = NULL;
 
                if (do_resample && status == SWITCH_STATUS_SUCCESS) {
                        status = SWITCH_STATUS_RESAMPLE;
@@ -1089,14 +1094,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
 
                        enc_frame = write_frame;
                        session->enc_write_frame.datalen = session->enc_write_frame.buflen;
-
+                       session->write_codec->session = session;
                        status = switch_core_codec_encode(session->write_codec,
                                                                                          frame->codec,
                                                                                          enc_frame->data,
                                                                                          enc_frame->datalen,
                                                                                          session->write_impl.actual_samples_per_second,
                                                                                          session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
-
+                       session->write_codec->session = NULL;
 
 
 
@@ -1193,14 +1198,14 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess
                                } else {
                                        rate = session->write_impl.actual_samples_per_second;
                                }
-
+                               session->write_codec->session = session;
                                status = switch_core_codec_encode(session->write_codec,
                                                                                                  frame->codec,
                                                                                                  enc_frame->data,
                                                                                                  enc_frame->datalen,
                                                                                                  rate,
                                                                                                  session->enc_write_frame.data, &session->enc_write_frame.datalen, &session->enc_write_frame.rate, &flag);
-
+                               session->write_codec->session = NULL;
 
                                switch (status) {
                                case SWITCH_STATUS_RESAMPLE:
index b0ccbb866fe87034f32ed792aa632dbeef14c1ef..4c16fadc5193e91a91d3c03662d72c6f41db9b8a 100644 (file)
@@ -62,6 +62,16 @@ SWITCH_DECLARE(switch_ivr_dmachine_t *) switch_core_session_get_dmachine(switch_
        return NULL;
 }
 
+
+SWITCH_DECLARE(stfu_instance_t *) switch_core_session_get_jb(switch_core_session_t *session, switch_media_type_t type)
+{
+       if (session->endpoint_interface->io_routines->get_jb) {
+               return session->endpoint_interface->io_routines->get_jb(session, type);
+       }
+
+       return NULL;
+}
+
 SWITCH_DECLARE(void) switch_core_session_soft_lock(switch_core_session_t *session, uint32_t sec)
 {
        session->soft_lock = sec;
index 63721e66fdd8d9490dc861c4cbbeb20cafbf8125..b6c1127b3157abe98844262a81d4fa4556dc6320 100644 (file)
@@ -2820,7 +2820,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
                        break;
                }
 
-               stfu_n_eat(jb, ts, read_frame->payload, read_frame->data, read_frame->datalen, 0);
+               stfu_n_eat(jb, ts, 0, read_frame->payload, read_frame->data, read_frame->datalen, 0);
                ts += read_impl.samples_per_packet;
 
                if ((jb_frame = stfu_n_read_a_frame(jb))) {
index 93eb42c6951f418c3ec4323160c77edbe93d546e..1b5925c23b1263204cfeaa14d153f6e4f2ea37c0 100644 (file)
@@ -53,7 +53,7 @@
 #define WRITE_INC(rtp_session)  switch_mutex_lock(rtp_session->write_mutex); rtp_session->writing++
 #define WRITE_DEC(rtp_session) switch_mutex_unlock(rtp_session->write_mutex); rtp_session->writing--
 
-#include "stfu.h"
+
 
 #define rtp_header_len 12
 #define RTP_START_PORT 16384
@@ -2148,6 +2148,15 @@ static void jb_callback(stfu_instance_t *i, void *udata)
 
 }
 
+SWITCH_DECLARE(stfu_instance_t *) switch_rtp_get_jitter_buffer(switch_rtp_t *rtp_session)
+{
+       if (!switch_rtp_ready(rtp_session) || !rtp_session->jb) {
+               return NULL;
+       }
+
+       return rtp_session->jb;
+}
+
 SWITCH_DECLARE(switch_status_t) switch_rtp_pause_jitter_buffer(switch_rtp_t *rtp_session, switch_bool_t pause)
 {
        
@@ -3019,6 +3028,7 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                }
 
                if (stfu_n_eat(rtp_session->jb, rtp_session->last_read_ts, 
+                                          ntohs((uint16_t) rtp_session->recv_msg.header.seq),
                                           rtp_session->recv_msg.header.pt,
                                           rtp_session->recv_msg.body, *bytes - rtp_header_len, rtp_session->timer.samplecount) == STFU_ITS_TOO_LATE) {