From 1b612fecb6e8db11da9b15c5522b87e7b642423d Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Tue, 2 Sep 2014 23:56:46 +0500 Subject: [PATCH] FS-6757 FS-6713 #comment please try latest master that has a new patch in it to address this issue --- src/include/private/switch_core_pvt.h | 3 ++ src/switch_core_io.c | 54 +++++++++++++++++++++- src/switch_ivr_async.c | 65 +++++++++++++-------------- 3 files changed, 86 insertions(+), 36 deletions(-) diff --git a/src/include/private/switch_core_pvt.h b/src/include/private/switch_core_pvt.h index d7933b4880..e64541b309 100644 --- a/src/include/private/switch_core_pvt.h +++ b/src/include/private/switch_core_pvt.h @@ -179,6 +179,9 @@ struct switch_core_session { switch_media_handle_t *media_handle; uint32_t decoder_errors; + switch_time_t last_read_time; + switch_time_t last_write_time; + }; struct switch_media_bug { diff --git a/src/switch_core_io.c b/src/switch_core_io.c index 1c2d0dbf14..337ccfc7fb 100644 --- a/src/switch_core_io.c +++ b/src/switch_core_io.c @@ -762,11 +762,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi switch_media_bug_t *bp; switch_bool_t ok = SWITCH_TRUE; int prune = 0; + switch_time_t now = switch_micro_time_now(); + switch_time_t diff = 0; + switch_size_t len = session->read_impl.decoded_bytes_per_packet; + unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; + switch_thread_rwlock_rdlock(session->bug_rwlock); + if (session->last_read_time && session->last_read_time < now) { + diff = ((now - session->last_read_time) + 3000 ) / session->read_impl.microseconds_per_packet; + + if (diff > 1) { + memset(fill_data, 255, len); + } + } + + session->last_read_time = switch_micro_time_now(); + for (bp = session->bugs; bp; bp = bp->next) { ok = SWITCH_TRUE; - + if (switch_channel_test_flag(session->channel, CF_PAUSE_BUGS) && !switch_core_media_bug_test_flag(bp, SMBF_NO_PAUSE)) { continue; } @@ -786,6 +801,17 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_frame(switch_core_sessi if (ok && bp->ready && switch_test_flag(bp, SMBF_READ_STREAM)) { switch_mutex_lock(bp->read_mutex); + + if (diff > 1) { + switch_time_t tdiff = diff; + + while(tdiff > 1) { + switch_buffer_write(bp->raw_read_buffer, fill_data, len); + tdiff--; + } + + } + if (bp->read_demux_frame) { uint8_t data[SWITCH_RECOMMENDED_BUFFER_SIZE]; int bytes = read_frame->datalen / 2; @@ -1341,8 +1367,23 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess if (session->bugs) { switch_media_bug_t *bp; int prune = 0; - + switch_time_t now = switch_micro_time_now(); + switch_time_t diff = 0; + switch_size_t len = session->read_impl.decoded_bytes_per_packet; + unsigned char fill_data[SWITCH_RECOMMENDED_BUFFER_SIZE] = {0}; + switch_thread_rwlock_rdlock(session->bug_rwlock); + + if (session->last_write_time && session->last_write_time < now) { + diff = ((now - session->last_write_time) + 3000 ) / session->read_impl.microseconds_per_packet; + + if (diff > 1) { + memset(fill_data, 255, len); + } + } + + session->last_write_time = switch_micro_time_now(); + for (bp = session->bugs; bp; bp = bp->next) { switch_bool_t ok = SWITCH_TRUE; @@ -1365,6 +1406,15 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_frame(switch_core_sess if (switch_test_flag(bp, SMBF_WRITE_STREAM)) { switch_mutex_lock(bp->write_mutex); + if (diff > 1) { + switch_time_t tdiff = diff; + + while(tdiff > 1) { + switch_buffer_write(bp->raw_read_buffer, fill_data, len); + tdiff--; + } + } + switch_buffer_write(bp->raw_write_buffer, write_frame->data, write_frame->datalen); switch_mutex_unlock(bp->write_mutex); diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4dad74c6f9..783d49143c 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1268,47 +1268,44 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s frame.data = data; frame.buflen = SWITCH_RECOMMENDED_BUFFER_SIZE; - for (;;) { - status = switch_core_media_bug_read(bug, &frame, SWITCH_FALSE); - if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) { + status = switch_core_media_bug_read(bug, &frame, SWITCH_FALSE); + + if (status == SWITCH_STATUS_SUCCESS || status == SWITCH_STATUS_BREAK) { - len = (switch_size_t) frame.datalen / 2; + len = (switch_size_t) frame.datalen / 2; - if (len && switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS && rh->hangup_on_error) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file); - switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); - switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); - return SWITCH_FALSE; - } + if (len && switch_core_file_write(rh->fh, mask ? null_data : data, &len) != SWITCH_STATUS_SUCCESS && rh->hangup_on_error) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Error writing %s\n", rh->file); + switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); + switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); + return SWITCH_FALSE; + } - /* check for silence timeout */ - if (rh->silence_threshold) { - switch_codec_implementation_t read_impl = { 0 }; - switch_core_session_get_read_impl(session, &read_impl); - if (is_silence_frame(&frame, rh->silence_threshold, &read_impl)) { - if (!rh->silence_time) { - /* start of silence */ - rh->silence_time = switch_micro_time_now(); - } else { - /* continuing silence */ - int duration_ms = (int)((switch_micro_time_now() - rh->silence_time) / 1000); - if (rh->silence_timeout_ms > 0 && duration_ms >= rh->silence_timeout_ms) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording file %s timeout: %i >= %i\n", rh->file, duration_ms, rh->silence_timeout_ms); - switch_core_media_bug_set_flag(bug, SMBF_PRUNE); - } - } - } else { /* not silence */ - if (rh->silence_time) { - /* end of silence */ - rh->silence_time = 0; - /* switch from initial timeout to final timeout */ - rh->silence_timeout_ms = rh->final_timeout_ms; + /* check for silence timeout */ + if (rh->silence_threshold) { + switch_codec_implementation_t read_impl = { 0 }; + switch_core_session_get_read_impl(session, &read_impl); + if (is_silence_frame(&frame, rh->silence_threshold, &read_impl)) { + if (!rh->silence_time) { + /* start of silence */ + rh->silence_time = switch_micro_time_now(); + } else { + /* continuing silence */ + int duration_ms = (int)((switch_micro_time_now() - rh->silence_time) / 1000); + if (rh->silence_timeout_ms > 0 && duration_ms >= rh->silence_timeout_ms) { + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Recording file %s timeout: %i >= %i\n", rh->file, duration_ms, rh->silence_timeout_ms); + switch_core_media_bug_set_flag(bug, SMBF_PRUNE); } } + } else { /* not silence */ + if (rh->silence_time) { + /* end of silence */ + rh->silence_time = 0; + /* switch from initial timeout to final timeout */ + rh->silence_timeout_ms = rh->final_timeout_ms; + } } - } else { - break; } } }