make a way to get the jitter buffer down to the codecs

This commit is contained in:
Anthony Minessale 2012-10-18 15:29:00 -04:00
parent 50cd5c28f5
commit 986fede6b0
14 changed files with 87 additions and 16 deletions

View 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;

View 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
}

View File

@ -106,6 +106,7 @@
#include <signal.h>
#include <errno.h>
#include "../../../libs/stfu/stfu.h"
#include "switch_platform.h"
#include "switch_types.h"
#include "switch_apr.h"
@ -138,9 +139,9 @@
#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

View 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);

View 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

View 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 */

View 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

View 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

View 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,

View 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 = {

View 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:

View 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;

View 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))) {

View 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) {