From 1b5fe102774ed4cd8edd38bf2a4cba68916f64ff Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 5 Mar 2007 20:53:54 +0000 Subject: [PATCH] change a few things to allow timers to generate timestamps git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@4452 d0543943-73ff-0310-b7d9-9358b9ac24b2 --- libs/iax/src/Makefile.in | 8 +++-- src/include/switch_frame.h | 2 +- src/include/switch_module_interfaces.h | 2 +- .../mod_conference/mod_conference.c | 2 ++ .../endpoints/mod_dingaling/mod_dingaling.c | 8 ++--- src/mod/endpoints/mod_sofia/mod_sofia.c | 10 +++--- src/mod/timers/mod_softtimer/mod_softtimer.c | 16 ++++++---- src/switch_core.c | 32 ++++++++++++++++--- src/switch_ivr.c | 16 ++++++++-- src/switch_rtp.c | 25 ++++++++++++--- 10 files changed, 89 insertions(+), 32 deletions(-) diff --git a/libs/iax/src/Makefile.in b/libs/iax/src/Makefile.in index 46fa9c29e1..146c0fe336 100644 --- a/libs/iax/src/Makefile.in +++ b/libs/iax/src/Makefile.in @@ -66,7 +66,8 @@ am__installdirs = "$(DESTDIR)$(pkgdir)" \ pkgLTLIBRARIES_INSTALL = $(INSTALL) LTLIBRARIES = $(pkg_LTLIBRARIES) libiax_la_LIBADD = -am_libiax_la_OBJECTS = iax2-parser.lo iax.lo md5.lo jitterbuf.lo +am_libiax_la_OBJECTS = iax2-parser.lo iax.lo md5.lo jitterbuf.lo \ + iax-mutex.lo libiax_la_OBJECTS = $(am_libiax_la_OBJECTS) DEFAULT_INCLUDES = -I. -I$(srcdir) depcomp = $(SHELL) $(top_srcdir)/build/depcomp @@ -196,9 +197,9 @@ AM_CPPFLAGS = $(AM_CFLAGS) AM_LDFLAGS = $(new_AM_LDFLAGS) pkgdir = $(libdir) pkg_LTLIBRARIES = libiax.la -libiax_la_SOURCES = iax2-parser.c iax.c md5.c jitterbuf.c +libiax_la_SOURCES = iax2-parser.c iax.c md5.c jitterbuf.c iax-mutex.c library_includedir = $(prefix)/include/iax -library_include_HEADERS = md5.h frame.h iax-client.h iax2.h iax2-parser.h iax.h +library_include_HEADERS = md5.h frame.h iax-client.h iax2.h iax2-parser.h iax.h iax-mutex.h noinst_HEADERS = jitterbuf.h all: all-am @@ -269,6 +270,7 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iax-mutex.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iax.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/iax2-parser.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/jitterbuf.Plo@am__quote@ diff --git a/src/include/switch_frame.h b/src/include/switch_frame.h index 10505e16ec..3ba59f32ee 100644 --- a/src/include/switch_frame.h +++ b/src/include/switch_frame.h @@ -63,7 +63,7 @@ struct switch_frame { /*! the payload of the frame */ switch_payload_t payload; /*! the timestamp of the frame */ - uint32_t timestamp; + switch_size_t timestamp; /*! frame flags */ switch_frame_flag_t flags; }; diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 3c69accbe6..b0996e64a1 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -225,7 +225,7 @@ struct switch_timer { /*! sample count to increment by on each cycle */ unsigned int samples; /*! current sample count based on samples parameter */ - unsigned int samplecount; + switch_size_t samplecount; /*! the timer interface provided from a loadable module */ switch_timer_interface_t *timer_interface; /*! the timer's memory pool */ diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 07166ea4aa..241eef3390 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1619,6 +1619,7 @@ static void conference_loop_output(conference_member_t *member) if (member->volume_out_level) { switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level); } + write_frame.timestamp = timer.samplecount; switch_core_session_write_frame(member->session, &write_frame, -1, 0); /* forget the conference data we played file node data instead */ @@ -1648,6 +1649,7 @@ static void conference_loop_output(conference_member_t *member) switch_change_sln_volume(write_frame.data, write_frame.samples, member->volume_out_level); } + write_frame.timestamp = timer.samplecount; switch_core_session_write_frame(member->session, &write_frame, -1, 0); } } diff --git a/src/mod/endpoints/mod_dingaling/mod_dingaling.c b/src/mod/endpoints/mod_dingaling/mod_dingaling.c index 904ad07d65..bb45781aa1 100644 --- a/src/mod/endpoints/mod_dingaling/mod_dingaling.c +++ b/src/mod/endpoints/mod_dingaling/mod_dingaling.c @@ -147,7 +147,7 @@ struct private_object { unsigned int cand_id; unsigned int desc_id; unsigned int dc; - int32_t timestamp_send; + switch_size_t timestamp_send; int32_t timestamp_recv; uint32_t last_read; char *codec_name; @@ -1356,12 +1356,12 @@ static switch_status_t channel_write_frame(switch_core_session_t *session, switc } samples = frames * tech_pvt->read_codec.implementation->samples_per_frame; - - if (switch_rtp_write_frame(tech_pvt->rtp_session, frame, samples) < 0) { + tech_pvt->timestamp_send += samples; + if (switch_rtp_write_frame(tech_pvt->rtp_session, frame, (uint32_t)tech_pvt->timestamp_send) < 0) { terminate_session(&session, __LINE__, SWITCH_CAUSE_NORMAL_CLEARING); return SWITCH_STATUS_FALSE; } - tech_pvt->timestamp_send += (int) samples; + switch_clear_flag_locked(tech_pvt, TFLAG_WRITING); diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 42989ebbad..a6588fab0b 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -276,7 +276,7 @@ struct private_object { switch_codec_t write_codec; uint32_t codec_ms; switch_caller_profile_t *caller_profile; - int32_t timestamp_send; + switch_size_t timestamp_send; //int32_t timestamp_recv; switch_rtp_t *rtp_session; int ssrc; @@ -682,7 +682,6 @@ static char *find_reg_url(sofia_profile_t *profile, const char *user, const char if (cbt.matches) { return val; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", user, host); return NULL; } } @@ -1881,9 +1880,8 @@ static switch_status_t sofia_write_frame(switch_core_session_t *session, switch_ tech_pvt->timestamp_send); #endif - switch_rtp_write_frame(tech_pvt->rtp_session, frame, samples); - - tech_pvt->timestamp_send += (int) samples; + tech_pvt->timestamp_send += samples; + switch_rtp_write_frame(tech_pvt->rtp_session, frame, (uint32_t)tech_pvt->timestamp_send); switch_clear_flag_locked(tech_pvt, TFLAG_WRITING); return status; @@ -2300,6 +2298,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session tech_pvt->dest = switch_core_session_strdup(nsession, buf); } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, host); cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION; terminate_session(&nsession, cause, __LINE__); goto done; @@ -2311,6 +2310,7 @@ static switch_call_cause_t sofia_outgoing_channel(switch_core_session_t *session tech_pvt->dest = switch_core_session_strdup(nsession, buf); } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot locate registered user %s@%s\n", dest, profile_name); cause = SWITCH_CAUSE_NO_ROUTE_DESTINATION; terminate_session(&nsession, cause, __LINE__); goto done; diff --git a/src/mod/timers/mod_softtimer/mod_softtimer.c b/src/mod/timers/mod_softtimer/mod_softtimer.c index b616fd0074..0505c83656 100644 --- a/src/mod/timers/mod_softtimer/mod_softtimer.c +++ b/src/mod/timers/mod_softtimer/mod_softtimer.c @@ -43,12 +43,12 @@ static const char modname[] = "mod_softtimer"; #define MAX_ELEMENTS 1000 struct timer_private { - uint64_t reference; + switch_size_t reference; }; typedef struct timer_private timer_private_t; struct timer_matrix { - uint64_t tick; + switch_size_t tick; uint32_t count; }; typedef struct timer_matrix timer_matrix_t; @@ -86,7 +86,9 @@ static inline switch_status_t timer_step(switch_timer_t *timer) return SWITCH_STATUS_FALSE; } - private_info->reference += timer->interval; + timer->samplecount = timer->samples * private_info->reference; + private_info->reference++;// timer->interval; + return SWITCH_STATUS_SUCCESS; } @@ -101,8 +103,7 @@ static inline switch_status_t timer_next(switch_timer_t *timer) switch_yield(1000); } - if (globals.RUNNING == 1) { - timer->samplecount += timer->samples; + if (globals.RUNNING == 1) { return SWITCH_STATUS_SUCCESS; } @@ -114,7 +115,7 @@ static inline switch_status_t timer_check(switch_timer_t *timer) { timer_private_t *private_info = timer->private_info; switch_status_t status = SWITCH_STATUS_SUCCESS; - uint64_t diff; + switch_size_t diff; if (globals.RUNNING != 1) { return SWITCH_STATUS_SUCCESS; @@ -210,7 +211,8 @@ SWITCH_MOD_DECLARE(switch_status_t) switch_module_runtime(void) index = (current_ms % i == 0) ? i : 0; if (TIMER_MATRIX[index].count) { - TIMER_MATRIX[index].tick += index; + //TIMER_MATRIX[index].tick += index; + TIMER_MATRIX[index].tick++; } } diff --git a/src/switch_core.c b/src/switch_core.c index 9a30285818..8b3cb12fa6 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -2173,15 +2173,21 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi &session->enc_read_frame.datalen, &session->enc_read_frame.rate, &flag); - + switch (status) { case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "fixme 1\n"); case SWITCH_STATUS_SUCCESS: + session->enc_read_frame.codec = session->read_codec; + session->enc_read_frame.samples = session->read_codec->implementation->bytes_per_frame / sizeof(int16_t); + session->enc_read_frame.timestamp = read_frame->timestamp; *frame = &session->enc_read_frame; break; case SWITCH_STATUS_NOOP: + session->raw_read_frame.codec = session->read_codec; + session->raw_read_frame.samples = session->read_codec->implementation->bytes_per_frame / sizeof(int16_t); + session->raw_read_frame.timestamp = read_frame->timestamp; *frame = &session->raw_read_frame; status = SWITCH_STATUS_SUCCESS; break; @@ -2439,9 +2445,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess case SWITCH_STATUS_RESAMPLE: switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "fixme 2\n"); case SWITCH_STATUS_SUCCESS: + session->enc_write_frame.codec = session->write_codec; + session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); + session->enc_write_frame.timestamp = frame->timestamp; write_frame = &session->enc_write_frame; break; case SWITCH_STATUS_NOOP: + enc_frame->codec = session->write_codec; + enc_frame->samples = enc_frame->datalen / sizeof(int16_t); + enc_frame->timestamp = frame->timestamp; + write_frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; @@ -2486,21 +2499,30 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess switch (status) { case SWITCH_STATUS_RESAMPLE: + session->enc_write_frame.codec = session->write_codec; + session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); + session->enc_write_frame.timestamp = frame->timestamp; + write_frame = &session->enc_write_frame; if (!session->read_resampler) { status = switch_resample_create(&session->read_resampler, frame->codec->implementation->samples_per_second, frame->codec->implementation->bytes_per_frame * 20, - session->write_codec->implementation-> - samples_per_second, - session->write_codec->implementation-> - bytes_per_frame * 20, session->pool); + session->write_codec->implementation->samples_per_second, + session->write_codec->implementation->bytes_per_frame * 20, + session->pool); } break; case SWITCH_STATUS_SUCCESS: + session->enc_write_frame.codec = session->write_codec; + session->enc_write_frame.samples = enc_frame->datalen / sizeof(int16_t); + session->enc_write_frame.timestamp = frame->timestamp; write_frame = &session->enc_write_frame; break; case SWITCH_STATUS_NOOP: + enc_frame->codec = session->write_codec; + enc_frame->samples = enc_frame->datalen / sizeof(int16_t); + enc_frame->timestamp = frame->timestamp; write_frame = enc_frame; status = SWITCH_STATUS_SUCCESS; break; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index f137c734e8..2915ba6f5f 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -1417,7 +1417,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess llen = olen; - + if (timer_name) { + write_frame.timestamp = timer.samplecount; + } #ifndef WIN32 #if __BYTE_ORDER == __BIG_ENDIAN if (!asis) {switch_swap_linear(write_frame.data, (int) write_frame.datalen / 2);} @@ -1689,6 +1691,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session write_frame.codec = codec; for( x = 0; !done && x < lead_in_out; x++) { + switch_yield(codec->implementation->microseconds_per_frame); + if (timer) { + write_frame.timestamp = timer->samplecount; + } if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n"); done = 1; @@ -1771,6 +1777,10 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session if (status != SWITCH_STATUS_SUCCESS) { for( x = 0; !done && x < lead_in_out; x++) { + switch_yield(codec->implementation->microseconds_per_frame); + if (timer) { + write_frame.timestamp = timer->samplecount; + } if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n"); done = 1; @@ -1789,7 +1799,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session write_frame.datalen = (uint32_t)ilen; write_frame.samples = (uint32_t)(ilen / 2); - + if (timer) { + write_frame.timestamp = timer->samplecount; + } if (switch_core_session_write_frame(session, &write_frame, -1, stream_id) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Bad Write\n"); done = 1; diff --git a/src/switch_rtp.c b/src/switch_rtp.c index c4dd487944..31ab9fc091 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -1303,18 +1303,24 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_enable_vad(switch_rtp_t *rtp_session, SWITCH_DECLARE(int) switch_rtp_write(switch_rtp_t *rtp_session, void *data, uint32_t datalen, uint32_t ts, switch_frame_flag_t *flags) { + uint8_t mark = 0; if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) || !rtp_session->remote_addr) { return -1; } - rtp_session->ts += ts; + rtp_session->ts = ts; + + if (rtp_session->ts > rtp_session->last_write_ts + rtp_session->packet_size) { + mark++; + } + rtp_session->seq = ntohs(rtp_session->seq) + 1; rtp_session->seq = htons(rtp_session->seq); rtp_session->send_msg.header.seq = rtp_session->seq; rtp_session->send_msg.header.ts = htonl(rtp_session->ts); - return rtp_common_write(rtp_session, data, datalen, 0, rtp_session->payload, flags); + return rtp_common_write(rtp_session, data, datalen, mark, rtp_session->payload, flags); } @@ -1324,6 +1330,7 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra uint8_t packetize = (rtp_session->packet_size > frame->datalen && (frame->payload == rtp_session->payload)) ? 1 : 0; void *data; uint32_t len; + uint8_t mark = 0; if (!switch_test_flag(rtp_session, SWITCH_RTP_FLAG_IO) || !rtp_session->remote_addr) { return -1; @@ -1335,14 +1342,24 @@ SWITCH_DECLARE(int) switch_rtp_write_frame(switch_rtp_t *rtp_session, switch_fra } else { data = frame->data; len = frame->datalen; - rtp_session->ts += ts; + + if (frame->timestamp) { + rtp_session->ts = (uint32_t) frame->timestamp; + } else { + rtp_session->ts = ts; + } + + if (rtp_session->ts > rtp_session->last_write_ts + rtp_session->packet_size) { + mark++; + } + rtp_session->seq = ntohs(rtp_session->seq) + 1; rtp_session->seq = htons(rtp_session->seq); rtp_session->send_msg.header.seq = rtp_session->seq; rtp_session->send_msg.header.ts = htonl(rtp_session->ts); } - return rtp_common_write(rtp_session, data, len, 0, rtp_session->payload, &frame->flags); + return rtp_common_write(rtp_session, data, len, mark, rtp_session->payload, &frame->flags); }