From 101b116daf1f2d9e2fefc66240e37eb91b56face Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 14 May 2013 11:22:48 -0500 Subject: [PATCH] FS-5011 try to fill gaps --- src/include/switch_core.h | 2 +- src/switch_core_io.c | 53 +++++++++++++++++++++++--------------- src/switch_ivr_async.c | 54 ++++++++++++++++++++++++++++++++++----- 3 files changed, 81 insertions(+), 28 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 5810899566..55ffb96cb2 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -2477,7 +2477,7 @@ SWITCH_DECLARE(void) switch_close_extra_files(int *keep, int keep_ttl); SWITCH_DECLARE(switch_status_t) switch_core_thread_set_cpu_affinity(int cpu); SWITCH_DECLARE(void) switch_os_yield(void); SWITCH_DECLARE(switch_status_t) switch_core_get_stacksizes(switch_size_t *cur, switch_size_t *max); - +SWITCH_DECLARE(void) switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len); SWITCH_DECLARE(switch_cache_db_handle_type_t) switch_core_dbtype(void); SWITCH_DECLARE(void) switch_core_sql_exec(const char *sql); diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 0d1c5fb367..ac2f187559 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -99,6 +99,34 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core return status; } +SWITCH_DECLARE(void) switch_core_gen_encoded_silence(unsigned char *data, const switch_codec_implementation_t *read_impl, switch_size_t len) +{ + unsigned char g729_filler[] = { + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, + 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, + 229, 127, 79, 96, 207, 82, 216, 110, 245, 81 + }; + + + if (read_impl->ianacode == 18 || switch_stristr("g729", read_impl->iananame)) { + memcpy(data, g729_filler, len); + } else { + memset(data, 255, len); + } + +} + SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { @@ -334,32 +362,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (bp->callback) { switch_frame_t tmp_frame = {0}; unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; - unsigned char g729_filler[] = { - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81, - 114, 170, 250, 103, 54, 211, 203, 194, 94, 64, - 229, 127, 79, 96, 207, 82, 216, 110, 245, 81 - }; + tmp_frame.codec = (*frame)->codec; tmp_frame.datalen = (*frame)->codec->implementation->encoded_bytes_per_packet; tmp_frame.samples = (*frame)->codec->implementation->samples_per_packet; tmp_frame.data = data; - - if ((*frame)->codec->implementation->ianacode == 18 || switch_stristr("g729", (*frame)->codec->implementation->iananame)) { - memcpy(tmp_frame.data, g729_filler, tmp_frame.datalen); - } - + + switch_core_gen_encoded_silence(data, (*frame)->codec->implementation, tmp_frame.datalen); + bp->native_read_frame = &tmp_frame; ok = bp->callback(bp, bp->user_data, SWITCH_ABC_TYPE_TAP_NATIVE_READ); bp->native_read_frame = NULL; diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 967db8679f..a9e86c9c65 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1090,11 +1090,14 @@ struct record_helper { switch_file_handle_t in_fh; switch_file_handle_t out_fh; int native; - int rready; - int wready; uint32_t packet_len; int min_sec; + int rready; + int wready; + switch_time_t last_read_time; + switch_time_t last_write_time; switch_bool_t hangup_on_error; + switch_codec_implementation_t read_impl; }; static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, switch_abc_type_t type) @@ -1116,29 +1119,68 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s switch_event_fire(&event); } + switch_core_session_get_read_impl(session, &rh->read_impl); + break; case SWITCH_ABC_TYPE_TAP_NATIVE_READ: { rh->rready = 1; - + if (rh->rready && rh->wready) { + switch_time_t now = switch_micro_time_now(); + long diff; nframe = switch_core_media_bug_get_native_read_frame(bug); len = nframe->datalen; - + + if (rh->last_read_time && rh->last_read_time < now) { + diff = ((now - rh->last_read_time) + 3000 ) / rh->read_impl.microseconds_per_packet; + + if (diff > 1) { + unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; + switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len); + + while(diff > 1) { + switch_size_t fill_len = len; + switch_core_file_write(&rh->in_fh, fill_data, &fill_len); + diff--; + } + } + } switch_core_file_write(&rh->in_fh, mask ? null_data : nframe->data, &len); + rh->last_read_time = now; } } break; case SWITCH_ABC_TYPE_TAP_NATIVE_WRITE: { rh->wready = 1; + + if (rh->rready && rh->wready) { + switch_time_t now = switch_micro_time_now(); + long diff; - if (rh->rready && rh->wready) { nframe = switch_core_media_bug_get_native_write_frame(bug); len = nframe->datalen; - switch_core_file_write(&rh->out_fh, mask ? null_data : nframe->data, &len); + + if (rh->last_write_time && rh->last_write_time < now) { + diff = ((now - rh->last_write_time) + 3000 ) / rh->read_impl.microseconds_per_packet; + + if (diff > 1) { + unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; + switch_core_gen_encoded_silence(fill_data, &rh->read_impl, len); + + while(diff > 1) { + switch_size_t fill_len = len; + switch_core_file_write(&rh->out_fh, fill_data, &fill_len); + diff--; + } + } + } + + switch_core_file_write(&rh->out_fh, mask ? null_data : nframe->data, &len); + rh->last_write_time = now; } } break;