From 295fcce8a80a98d84b674a17e7e2da7db56db04a Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Wed, 17 Sep 2014 04:54:38 +0500 Subject: [PATCH] add buffer_seconds param to shout filehandles to override the original default of 1 and remove previous code to attempt to buffer several seconds of audio in the open routine. Any experiencing jittery playback from slow shout destinations should add {buffer_seconds=N} to the file path to increase the amount of time allotted for buffering when no audio is discovered on the wire --- src/mod/formats/mod_shout/mod_shout.c | 36 +++++++++++++-------------- src/switch_ivr_play_say.c | 1 + 2 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index ae1ee83d38..6dfa0726ea 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -130,6 +130,7 @@ struct shout_context { unsigned char *mp3buf; switch_size_t mp3buflen; switch_thread_rwlock_t *rwlock; + int buffer_seconds; }; typedef struct shout_context shout_context_t; @@ -477,27 +478,12 @@ static void launch_read_stream_thread(shout_context_t *context) { switch_thread_t *thread; switch_threadattr_t *thd_attr = NULL; - int sanity = 10; - size_t used; context->thread_running = 1; switch_threadattr_create(&thd_attr, context->memory_pool); switch_threadattr_detach_set(thd_attr, 1); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&thread, thd_attr, read_stream_thread, context, context->memory_pool); - - while (context->thread_running && --sanity) { - /* at least 1s of audio and up to 5s initialize */ - switch_mutex_lock(context->audio_mutex); - used = switch_buffer_inuse(context->audio_buffer); - switch_mutex_unlock(context->audio_mutex); - - if (used >= (2 * context->samplerate)) { - break; - } - - switch_yield(500000); - } } #define error_check() if (context->err) goto error; @@ -628,6 +614,7 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char long rate = 0; int channels = 0; int encoding = 0; + const char *var = NULL; if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) { return SWITCH_STATUS_MEMERR; @@ -640,6 +627,7 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char context->memory_pool = handle->memory_pool; context->samplerate = handle->samplerate; context->handle = handle; + context->buffer_seconds = 1; switch_thread_rwlock_create(&(context->rwlock), context->memory_pool); @@ -647,6 +635,17 @@ static switch_status_t shout_file_open(switch_file_handle_t *handle, const char switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->memory_pool); + if (handle->params && (var = switch_event_get_header(handle->params, "buffer_seconds"))) { + int bs = atol(var); + if (bs < 1) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Buffer Seconds %d too low\n", bs); + } else if (bs > 60) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Buffer Seconds %d too high\n", bs); + } else { + context->buffer_seconds = bs; + } + } + if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) { if (switch_buffer_create_dynamic(&context->audio_buffer, TC_BUFFER_SIZE, TC_BUFFER_SIZE * 2, 0) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n"); @@ -944,12 +943,13 @@ static switch_status_t shout_file_read(switch_file_handle_t *handle, void *data, if (rb) { *len = rb / sizeof(int16_t) / handle->real_channels; } else { - /* no data, so insert 1 second of silence */ - newbytes = 2 * handle->samplerate; + /* no data, so insert N seconds of silence */ + newbytes = (2 * handle->samplerate * handle->real_channels) * context->buffer_seconds; if (newbytes < bytes) { bytes = newbytes; } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Padding mp3 stream with 1s of empty audio. (%s)\n", context->stream_url); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Padding mp3 stream with %ds of empty audio. (%s)\n", + context->buffer_seconds, context->stream_url); memset(data, 255, bytes); *len = bytes / sizeof(int16_t) / handle->real_channels; diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index f487fcec78..24a4ede9b1 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -1238,6 +1238,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess continue; } + switch_channel_audio_sync(channel); switch_core_session_io_write_lock(session); switch_channel_set_private(channel, "__fh", fh); switch_core_session_io_rwunlock(session);