FS-8811 #comment please test
This commit is contained in:
parent
c366e3615f
commit
66fe6e5a46
|
@ -2808,6 +2808,8 @@ SWITCH_STANDARD_APP(playback_function)
|
||||||
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
|
switch_channel_set_variable(channel, SWITCH_PLAYBACK_TERMINATOR_USED, "");
|
||||||
|
|
||||||
status = switch_ivr_play_file(session, &fh, file, &args);
|
status = switch_ivr_play_file(session, &fh, file, &args);
|
||||||
|
switch_assert(!(fh.flags & SWITCH_FILE_OPEN));
|
||||||
|
|
||||||
|
|
||||||
switch (status) {
|
switch (status) {
|
||||||
case SWITCH_STATUS_SUCCESS:
|
case SWITCH_STATUS_SUCCESS:
|
||||||
|
|
|
@ -68,10 +68,13 @@ struct local_stream_context {
|
||||||
int sent_png;
|
int sent_png;
|
||||||
int last_w;
|
int last_w;
|
||||||
int last_h;
|
int last_h;
|
||||||
|
int newres;
|
||||||
int serno;
|
int serno;
|
||||||
int pop_count;
|
int pop_count;
|
||||||
|
switch_size_t blank;
|
||||||
switch_image_t *banner_img;
|
switch_image_t *banner_img;
|
||||||
switch_time_t banner_timeout;
|
switch_time_t banner_timeout;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
struct local_stream_context *next;
|
struct local_stream_context *next;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -116,6 +119,7 @@ struct local_stream_source {
|
||||||
int serno;
|
int serno;
|
||||||
switch_size_t abuflen;
|
switch_size_t abuflen;
|
||||||
switch_byte_t *abuf;
|
switch_byte_t *abuf;
|
||||||
|
switch_timer_t timer;
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct local_stream_source local_stream_source_t;
|
typedef struct local_stream_source local_stream_source_t;
|
||||||
|
@ -173,28 +177,30 @@ switch_status_t list_streams(const char *line, const char *cursor, switch_consol
|
||||||
|
|
||||||
static int do_rand(uint32_t count)
|
static int do_rand(uint32_t count)
|
||||||
{
|
{
|
||||||
double r;
|
int r = 0;
|
||||||
int index;
|
|
||||||
|
|
||||||
if (count < 3) return 0;
|
switch_mutex_lock(globals.mutex);
|
||||||
|
r = (rand() % count) + 1;
|
||||||
|
switch_mutex_unlock(globals.mutex);
|
||||||
|
|
||||||
r = ((double) rand() / ((double) (RAND_MAX) + (double) (1)));
|
return r;
|
||||||
index = (int) (r * count) + 1;
|
|
||||||
|
|
||||||
return index;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void flush_video_queue(switch_queue_t *q)
|
static void flush_video_queue(switch_queue_t *q)
|
||||||
{
|
{
|
||||||
void *pop;
|
void *pop = NULL;
|
||||||
|
|
||||||
if (switch_queue_size(q) == 0) {
|
if (switch_queue_size(q) == 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) {
|
while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||||
|
if (pop) {
|
||||||
switch_image_t *img = (switch_image_t *) pop;
|
switch_image_t *img = (switch_image_t *) pop;
|
||||||
switch_img_free(&img);
|
switch_img_free(&img);
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -204,8 +210,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
volatile local_stream_source_t *s = (local_stream_source_t *) obj;
|
volatile local_stream_source_t *s = (local_stream_source_t *) obj;
|
||||||
local_stream_source_t *source = (local_stream_source_t *) s;
|
local_stream_source_t *source = (local_stream_source_t *) s;
|
||||||
switch_file_handle_t fh = { 0 };
|
switch_file_handle_t fh = { 0 };
|
||||||
char file_buf[128] = "", path_buf[512] = "", last_path[512], png_buf[512] = "", tmp_buf[512] = "";
|
char file_buf[128] = "", path_buf[512] = "", last_path[512] = "", png_buf[512] = "", tmp_buf[512] = "";
|
||||||
switch_timer_t timer = { 0 };
|
|
||||||
int fd = -1;
|
int fd = -1;
|
||||||
switch_buffer_t *audio_buffer;
|
switch_buffer_t *audio_buffer;
|
||||||
switch_byte_t *dist_buf;
|
switch_byte_t *dist_buf;
|
||||||
|
@ -227,12 +232,21 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
do_shuffle = 1;
|
do_shuffle = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (source->prebuf < source->abuflen) {
|
||||||
|
source->prebuf = source->abuflen;
|
||||||
|
}
|
||||||
|
|
||||||
switch_queue_create(&source->video_q, 500, source->pool);
|
switch_queue_create(&source->video_q, 500, source->pool);
|
||||||
switch_buffer_create_dynamic(&audio_buffer, 1024, source->prebuf + 10, 0);
|
switch_buffer_create_dynamic(&audio_buffer, 1024, source->prebuf + 10, 0);
|
||||||
dist_buf = switch_core_alloc(source->pool, source->prebuf + 10);
|
dist_buf = switch_core_alloc(source->pool, source->prebuf + 10);
|
||||||
|
|
||||||
switch_thread_rwlock_create(&source->rwlock, source->pool);
|
switch_thread_rwlock_create(&source->rwlock, source->pool);
|
||||||
|
|
||||||
|
if (switch_core_timer_init(&source->timer, source->timer_name, source->interval, (int)source->samples, source->pool) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
|
||||||
|
RUNNING = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (RUNNING) {
|
if (RUNNING) {
|
||||||
source->ready = 1;
|
source->ready = 1;
|
||||||
switch_mutex_lock(globals.mutex);
|
switch_mutex_lock(globals.mutex);
|
||||||
|
@ -243,6 +257,11 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
while (RUNNING && !source->stopped && source->ready) {
|
while (RUNNING && !source->stopped && source->ready) {
|
||||||
const char *fname;
|
const char *fname;
|
||||||
|
|
||||||
|
if (source->dir_handle) {
|
||||||
|
switch_dir_close(source->dir_handle);
|
||||||
|
source->dir_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
if (temp_pool) {
|
if (temp_pool) {
|
||||||
switch_core_destroy_memory_pool(&temp_pool);
|
switch_core_destroy_memory_pool(&temp_pool);
|
||||||
}
|
}
|
||||||
|
@ -277,6 +296,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
while (RUNNING && !source->stopped) {
|
while (RUNNING && !source->stopped) {
|
||||||
switch_size_t olen;
|
switch_size_t olen;
|
||||||
const char *artist = NULL, *title = NULL;
|
const char *artist = NULL, *title = NULL;
|
||||||
|
char tmp_space[128] = "";
|
||||||
|
|
||||||
if (fd > -1) {
|
if (fd > -1) {
|
||||||
char *pb;
|
char *pb;
|
||||||
|
@ -305,6 +325,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (dir_count > 1 && !strcmp(last_path, path_buf)) {
|
if (dir_count > 1 && !strcmp(last_path, path_buf)) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -328,25 +349,19 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_buffer_zero(audio_buffer);
|
||||||
|
|
||||||
if (switch_core_file_has_video(&fh)) {
|
if (switch_core_file_has_video(&fh)) {
|
||||||
flush_video_queue(source->video_q);
|
flush_video_queue(source->video_q);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_buffer_zero(audio_buffer);
|
|
||||||
|
|
||||||
if (switch_core_timer_init(&timer, source->timer_name, source->interval, (int)source->samples, temp_pool) != SWITCH_STATUS_SUCCESS) {
|
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Can't start timer.\n");
|
|
||||||
switch_dir_close(source->dir_handle);
|
|
||||||
source->dir_handle = NULL;
|
|
||||||
goto done;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_img_free(&source->cover_art);
|
switch_img_free(&source->cover_art);
|
||||||
switch_set_string(tmp_buf, path_buf);
|
switch_set_string(tmp_buf, path_buf);
|
||||||
|
|
||||||
if ((p = strrchr(tmp_buf, '/'))) {
|
if ((p = strrchr(tmp_buf, '/'))) {
|
||||||
*p++ = '\0';
|
*p++ = '\0';
|
||||||
switch_snprintf(png_buf, sizeof(png_buf), "%s/art/%s.png", tmp_buf, p);
|
switch_snprintf(png_buf, sizeof(png_buf), "%s/art/%s.png", tmp_buf, p);
|
||||||
if (switch_file_exists(png_buf, source->pool) == SWITCH_STATUS_SUCCESS) {
|
if (switch_file_exists(png_buf, temp_pool) == SWITCH_STATUS_SUCCESS) {
|
||||||
source->cover_art = switch_img_read_png(png_buf, SWITCH_IMG_FMT_I420);
|
source->cover_art = switch_img_read_png(png_buf, SWITCH_IMG_FMT_I420);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -358,6 +373,51 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, &artist);
|
switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_ARTIST, &artist);
|
||||||
switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_TITLE, &title);
|
switch_core_file_get_string(&fh, SWITCH_AUDIO_COL_STR_TITLE, &title);
|
||||||
|
|
||||||
|
if (!title && !artist) {
|
||||||
|
char *e, *p, *args[3];
|
||||||
|
int argc;
|
||||||
|
|
||||||
|
switch_set_string(tmp_space, path_buf);
|
||||||
|
p = tmp_space;
|
||||||
|
|
||||||
|
while((e = strchr(p, '/'))) {
|
||||||
|
*e = '\0';
|
||||||
|
p = e+1;
|
||||||
|
}
|
||||||
|
|
||||||
|
argc = switch_split(p, '-', args);
|
||||||
|
|
||||||
|
if (argc > 0) {
|
||||||
|
while(*args[0] == ' ') {
|
||||||
|
args[0]++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while(end_of(args[0]) == ' ') {
|
||||||
|
end_of(args[0]) = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
|
artist = args[0];
|
||||||
|
|
||||||
|
if (argc > 1) {
|
||||||
|
while(*args[1] == ' ') {
|
||||||
|
args[1]++;
|
||||||
|
}
|
||||||
|
while(end_of(args[1]) == ' ') {
|
||||||
|
end_of(args[1]) = '\0';
|
||||||
|
}
|
||||||
|
title = args[1];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!title) {
|
||||||
|
title = artist;
|
||||||
|
artist = NULL;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
title = p;
|
||||||
|
artist = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (title && (source->cover_art || switch_core_file_has_video(&fh))) {
|
if (title && (source->cover_art || switch_core_file_has_video(&fh))) {
|
||||||
const char *format = "#cccccc:#333333:FreeSans.ttf:3%:";
|
const char *format = "#cccccc:#333333:FreeSans.ttf:3%:";
|
||||||
|
|
||||||
|
@ -368,11 +428,12 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
while (RUNNING && !source->stopped) {
|
while (RUNNING && !source->stopped) {
|
||||||
int is_open;
|
int is_open;
|
||||||
switch_file_handle_t *use_fh = &fh;
|
switch_file_handle_t *use_fh = &fh;
|
||||||
|
|
||||||
switch_core_timer_next(&timer);
|
switch_core_timer_next(&source->timer);
|
||||||
olen = source->samples;
|
olen = source->samples;
|
||||||
|
|
||||||
if (source->chime_total) {
|
if (source->chime_total) {
|
||||||
|
@ -422,6 +483,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
|
|
||||||
switch_core_file_close(use_fh);
|
switch_core_file_close(use_fh);
|
||||||
flush_video_queue(source->video_q);
|
flush_video_queue(source->video_q);
|
||||||
|
switch_buffer_zero(audio_buffer);
|
||||||
if (use_fh == &source->chime_fh) {
|
if (use_fh == &source->chime_fh) {
|
||||||
source->chime_counter = source->rate * source->chime_freq;
|
source->chime_counter = source->rate * source->chime_freq;
|
||||||
switch_core_file_close(&fh);
|
switch_core_file_close(&fh);
|
||||||
|
@ -431,10 +493,7 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!is_open) {
|
if (is_open) {
|
||||||
switch_buffer_zero(audio_buffer);
|
|
||||||
break;
|
|
||||||
} else {
|
|
||||||
int svr = 0;
|
int svr = 0;
|
||||||
|
|
||||||
if (switch_core_has_video() && switch_core_file_has_video(use_fh)) {
|
if (switch_core_has_video() && switch_core_file_has_video(use_fh)) {
|
||||||
|
@ -473,6 +532,8 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
olen = source->samples;
|
olen = source->samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
switch_assert(source->abuflen >= olen * 2 * source->channels);
|
||||||
|
|
||||||
if (switch_core_file_read(use_fh, source->abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
|
if (switch_core_file_read(use_fh, source->abuf, &olen) != SWITCH_STATUS_SUCCESS || !olen) {
|
||||||
switch_core_file_close(use_fh);
|
switch_core_file_close(use_fh);
|
||||||
flush_video_queue(source->video_q);
|
flush_video_queue(source->video_q);
|
||||||
|
@ -510,23 +571,27 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
source->prebuf = (uint32_t)(source->samples * 2 * source->channels);
|
|
||||||
|
|
||||||
if (!source->total) {
|
if (!source->total) {
|
||||||
flush_video_queue(source->video_q);
|
flush_video_queue(source->video_q);
|
||||||
switch_buffer_zero(audio_buffer);
|
switch_buffer_zero(audio_buffer);
|
||||||
} else if (used > source->samples * 2 * source->channels) {
|
} else if (used && (!is_open || used >= source->abuflen)) {
|
||||||
//if (!is_open || used >= source->prebuf || (source->total && used > source->samples * 2 * source->channels)) {
|
|
||||||
void *pop;
|
void *pop;
|
||||||
uint32_t bused;
|
uint32_t bused = 0;
|
||||||
local_stream_context_t *cp = NULL;
|
local_stream_context_t *cp = NULL;
|
||||||
|
|
||||||
used = switch_buffer_read(audio_buffer, dist_buf, source->samples * 2 * source->channels);
|
switch_assert(source->abuflen <= source->prebuf);
|
||||||
|
used = switch_buffer_read(audio_buffer, dist_buf, source->abuflen);
|
||||||
bused = 0;
|
|
||||||
|
|
||||||
switch_mutex_lock(source->mutex);
|
switch_mutex_lock(source->mutex);
|
||||||
for (cp = source->context_list; cp && RUNNING; cp = cp->next) {
|
for (cp = source->context_list; cp && RUNNING; cp = cp->next) {
|
||||||
|
|
||||||
|
if (!cp->ready) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch_mutex_lock(cp->audio_mutex);
|
||||||
|
|
||||||
|
if (switch_test_flag(cp->handle, SWITCH_FILE_OPEN)) {
|
||||||
if (source->has_video) {
|
if (source->has_video) {
|
||||||
switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO);
|
switch_set_flag(cp->handle, SWITCH_FILE_FLAG_VIDEO);
|
||||||
} else {
|
} else {
|
||||||
|
@ -534,11 +599,13 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
|
|
||||||
if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) {
|
if (switch_test_flag(cp->handle, SWITCH_FILE_CALLBACK)) {
|
||||||
|
switch_mutex_unlock(cp->audio_mutex);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
switch_mutex_lock(cp->audio_mutex);
|
|
||||||
bused = (uint32_t)switch_buffer_inuse(cp->audio_buffer);
|
bused = (uint32_t)switch_buffer_inuse(cp->audio_buffer);
|
||||||
|
|
||||||
if (bused > source->samples * 768) {
|
if (bused > source->samples * 768) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n",
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Flushing Stream Handle Buffer [%s() %s:%d] size: %u samples: %ld\n",
|
||||||
cp->func, cp->file, cp->line, bused, (long)source->samples);
|
cp->func, cp->file, cp->line, bused, (long)source->samples);
|
||||||
|
@ -552,15 +619,24 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
|
|
||||||
|
|
||||||
while (switch_queue_trypop(source->video_q, &pop) == SWITCH_STATUS_SUCCESS) {
|
while (switch_queue_trypop(source->video_q, &pop) == SWITCH_STATUS_SUCCESS) {
|
||||||
switch_image_t *img = (switch_image_t *) pop;
|
switch_image_t *img;
|
||||||
switch_image_t *imgcp = NULL;
|
switch_image_t *imgcp = NULL;
|
||||||
|
|
||||||
|
if (!pop) break;
|
||||||
|
|
||||||
|
img = (switch_image_t *) pop;
|
||||||
|
|
||||||
|
switch_mutex_lock(source->mutex);
|
||||||
|
if (source->context_list) {
|
||||||
if (source->total == 1) {
|
if (source->total == 1) {
|
||||||
switch_queue_push(source->context_list->video_q, img);
|
switch_queue_push(source->context_list->video_q, img);
|
||||||
} else {
|
} else {
|
||||||
if (source->context_list) {
|
|
||||||
switch_mutex_lock(source->mutex);
|
|
||||||
for (cp = source->context_list; cp && RUNNING; cp = cp->next) {
|
for (cp = source->context_list; cp && RUNNING; cp = cp->next) {
|
||||||
|
|
||||||
|
if (!cp->ready) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if (cp->video_q) {
|
if (cp->video_q) {
|
||||||
imgcp = NULL;
|
imgcp = NULL;
|
||||||
switch_img_copy(img, &imgcp);
|
switch_img_copy(img, &imgcp);
|
||||||
|
@ -571,23 +647,19 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
switch_mutex_unlock(source->mutex);
|
|
||||||
}
|
|
||||||
switch_img_free(&img);
|
switch_img_free(&img);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
switch_mutex_unlock(source->mutex);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_core_timer_destroy(&timer);
|
|
||||||
if (RUNNING && source->shuffle) {
|
if (RUNNING && source->shuffle) {
|
||||||
skip = do_rand(dir_count);
|
skip = do_rand(dir_count);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_dir_close(source->dir_handle);
|
|
||||||
source->dir_handle = NULL;
|
|
||||||
|
|
||||||
if (source->full_reload) {
|
if (source->full_reload) {
|
||||||
if (source->rwlock && switch_thread_rwlock_trywrlock(source->rwlock) != SWITCH_STATUS_SUCCESS) {
|
if (source->rwlock && switch_thread_rwlock_trywrlock(source->rwlock) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cannot stop local_stream://%s because it is in use.\n",source->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Cannot stop local_stream://%s because it is in use.\n",source->name);
|
||||||
|
@ -635,6 +707,9 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
}
|
}
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s partially reloaded.\n",source->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s partially reloaded.\n",source->name);
|
||||||
source->part_reload = 0;
|
source->part_reload = 0;
|
||||||
|
if (source->timer.interval) {
|
||||||
|
switch_core_timer_destroy(&source->timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s fully reloaded.\n",source->name);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "local_stream://%s fully reloaded.\n",source->name);
|
||||||
|
@ -647,6 +722,15 @@ static void *SWITCH_THREAD_FUNC read_stream_thread(switch_thread_t *thread, void
|
||||||
|
|
||||||
done:
|
done:
|
||||||
|
|
||||||
|
if (source->dir_handle) {
|
||||||
|
switch_dir_close(source->dir_handle);
|
||||||
|
source->dir_handle = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (source->timer.interval) {
|
||||||
|
switch_core_timer_destroy(&source->timer);
|
||||||
|
}
|
||||||
|
|
||||||
switch_safe_free(source->banner_txt);
|
switch_safe_free(source->banner_txt);
|
||||||
|
|
||||||
if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) {
|
if (switch_test_flag((&fh), SWITCH_FILE_OPEN)) {
|
||||||
|
@ -692,6 +776,7 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||||
local_stream_source_t *source;
|
local_stream_source_t *source;
|
||||||
char *alt_path = NULL;
|
char *alt_path = NULL;
|
||||||
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
switch_status_t status = SWITCH_STATUS_SUCCESS;
|
||||||
|
switch_memory_pool_t *pool;
|
||||||
|
|
||||||
/* already buffering a step back, so always disable it */
|
/* already buffering a step back, so always disable it */
|
||||||
handle->pre_buffer_datalen = 0;
|
handle->pre_buffer_datalen = 0;
|
||||||
|
@ -727,11 +812,20 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||||
goto end;
|
goto end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((context = switch_core_alloc(handle->memory_pool, sizeof(*context))) == 0) {
|
//if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
|
||||||
|
// switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
|
||||||
|
// abort();
|
||||||
|
//}
|
||||||
|
|
||||||
|
pool = handle->memory_pool;
|
||||||
|
|
||||||
|
if ((context = switch_core_alloc(pool, sizeof(*context))) == 0) {
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_queue_create(&context->video_q, 500, handle->memory_pool);
|
context->pool = pool;
|
||||||
|
|
||||||
|
switch_queue_create(&context->video_q, 500, context->pool);
|
||||||
|
|
||||||
handle->samples = 0;
|
handle->samples = 0;
|
||||||
handle->samplerate = source->rate;
|
handle->samplerate = source->rate;
|
||||||
|
@ -744,7 +838,7 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||||
handle->interval = source->interval;
|
handle->interval = source->interval;
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening Stream [%s] %dhz\n", path, handle->samplerate);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opening Stream [%s] %dhz\n", path, handle->samplerate);
|
||||||
|
|
||||||
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, handle->memory_pool);
|
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||||
if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) {
|
if (switch_buffer_create_dynamic(&context->audio_buffer, 512, 1024, 0) != SWITCH_STATUS_SUCCESS) {
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Memory Error!\n");
|
||||||
status = SWITCH_STATUS_MEMERR;
|
status = SWITCH_STATUS_MEMERR;
|
||||||
|
@ -779,36 +873,50 @@ static switch_status_t local_stream_file_open(switch_file_handle_t *handle, cons
|
||||||
|
|
||||||
static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
|
static switch_status_t local_stream_file_close(switch_file_handle_t *handle)
|
||||||
{
|
{
|
||||||
local_stream_context_t *cp, *last = NULL, *context = handle->private_info;
|
local_stream_context_t *context = NULL, *last = NULL, *cp = NULL;
|
||||||
|
local_stream_source_t *source;
|
||||||
|
|
||||||
|
context = handle->private_info;
|
||||||
|
switch_assert(context);
|
||||||
|
|
||||||
|
//pool = context->pool;
|
||||||
|
source = context->source;
|
||||||
context->ready = 0;
|
context->ready = 0;
|
||||||
|
|
||||||
switch_mutex_lock(context->source->mutex);
|
switch_mutex_lock(source->mutex);
|
||||||
for (cp = context->source->context_list; cp; cp = cp->next) {
|
for (cp = source->context_list; cp; cp = cp->next) {
|
||||||
if (cp == context) {
|
if (cp == context) {
|
||||||
if (last) {
|
if (last) {
|
||||||
last->next = cp->next;
|
last->next = cp->next;
|
||||||
} else {
|
} else {
|
||||||
context->source->context_list = cp->next;
|
source->context_list = cp->next;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
last = cp;
|
last = cp;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (context->source->has_video) {
|
switch_mutex_lock(context->audio_mutex);
|
||||||
|
|
||||||
|
if (source->has_video) {
|
||||||
flush_video_queue(context->video_q);
|
flush_video_queue(context->video_q);
|
||||||
switch_queue_trypush(context->video_q, NULL);
|
switch_queue_trypush(context->video_q, NULL);
|
||||||
switch_queue_interrupt_all(context->video_q);
|
switch_queue_interrupt_all(context->video_q);
|
||||||
flush_video_queue(context->video_q);
|
flush_video_queue(context->video_q);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_img_free(&context->banner_img);
|
source->total--;
|
||||||
|
|
||||||
context->source->total--;
|
switch_img_free(&context->banner_img);
|
||||||
switch_mutex_unlock(context->source->mutex);
|
|
||||||
switch_buffer_destroy(&context->audio_buffer);
|
switch_buffer_destroy(&context->audio_buffer);
|
||||||
switch_thread_rwlock_unlock(context->source->rwlock);
|
switch_mutex_unlock(context->audio_mutex);
|
||||||
|
//switch_core_destroy_memory_pool(&pool);
|
||||||
|
|
||||||
|
context->handle = NULL;
|
||||||
|
handle->private_info = NULL;
|
||||||
|
switch_mutex_unlock(source->mutex);
|
||||||
|
|
||||||
|
switch_thread_rwlock_unlock(source->rwlock);
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
@ -887,6 +995,9 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||||
|
|
||||||
frame->img = (switch_image_t *) pop;
|
frame->img = (switch_image_t *) pop;
|
||||||
context->sent_png = 0;
|
context->sent_png = 0;
|
||||||
|
if (frame->img->d_w != context->last_w || frame->img->d_h != context->last_h) {
|
||||||
|
context->newres = 1;
|
||||||
|
}
|
||||||
context->last_w = frame->img->d_w;
|
context->last_w = frame->img->d_w;
|
||||||
context->last_h = frame->img->d_h;
|
context->last_h = frame->img->d_h;
|
||||||
goto got_img;
|
goto got_img;
|
||||||
|
@ -920,6 +1031,10 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||||
|
|
||||||
if (context->source->banner_txt) {
|
if (context->source->banner_txt) {
|
||||||
if ((!context->banner_timeout || context->banner_timeout >= now)) {
|
if ((!context->banner_timeout || context->banner_timeout >= now)) {
|
||||||
|
if (context->newres) {
|
||||||
|
switch_img_free(&context->banner_img);
|
||||||
|
context->newres = 0;
|
||||||
|
}
|
||||||
if (!context->banner_img) {
|
if (!context->banner_img) {
|
||||||
context->banner_img = switch_img_write_text_img(context->last_w, context->last_h, SWITCH_TRUE, context->source->banner_txt);
|
context->banner_img = switch_img_write_text_img(context->last_w, context->last_h, SWITCH_TRUE, context->source->banner_txt);
|
||||||
context->banner_timeout = now + 5000000;
|
context->banner_timeout = now + 5000000;
|
||||||
|
@ -935,6 +1050,7 @@ static switch_status_t local_stream_file_read_video(switch_file_handle_t *handle
|
||||||
if (frame->img && context->banner_img && frame->img->d_w >= context->banner_img->d_w) {
|
if (frame->img && context->banner_img && frame->img->d_w >= context->banner_img->d_w) {
|
||||||
//switch_img_overlay(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h, 100);
|
//switch_img_overlay(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h, 100);
|
||||||
switch_img_patch(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h);
|
switch_img_patch(frame->img, context->banner_img, 0, frame->img->d_h - context->banner_img->d_h);
|
||||||
|
//switch_img_patch(frame->img, context->banner_img, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
|
@ -944,29 +1060,36 @@ static switch_status_t local_stream_file_read(switch_file_handle_t *handle, void
|
||||||
{
|
{
|
||||||
local_stream_context_t *context = handle->private_info;
|
local_stream_context_t *context = handle->private_info;
|
||||||
switch_size_t bytes = 0;
|
switch_size_t bytes = 0;
|
||||||
size_t need = *len * 2 * handle->real_channels;
|
size_t need;
|
||||||
|
|
||||||
if (!context->source->ready) {
|
if (!(context->ready && context->source->ready)) {
|
||||||
*len = 0;
|
*len = 0;
|
||||||
return SWITCH_STATUS_FALSE;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch_mutex_lock(context->audio_mutex);
|
switch_mutex_lock(context->audio_mutex);
|
||||||
|
need = *len * 2 * context->source->channels;
|
||||||
|
|
||||||
if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) {
|
if ((bytes = switch_buffer_read(context->audio_buffer, data, need))) {
|
||||||
*len = bytes / 2 / handle->real_channels;
|
*len = bytes / 2 / context->source->channels;
|
||||||
} else {
|
} else {
|
||||||
size_t blank = (handle->samplerate / 20) * 2 * handle->real_channels;
|
size_t blank;
|
||||||
|
|
||||||
|
switch_assert(handle->samplerate <= 48000);
|
||||||
|
switch_assert(handle->real_channels <= 2);
|
||||||
|
|
||||||
|
blank = (handle->samplerate / 4) * 2 * handle->real_channels;
|
||||||
|
|
||||||
if (need > blank) {
|
if (need > blank) {
|
||||||
need = blank;
|
need = blank;
|
||||||
}
|
}
|
||||||
|
|
||||||
memset(data, 0, need);
|
memset(data, 0, need);
|
||||||
*len = need / 2 / handle->real_channels;
|
*len = need / 2 / context->source->channels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
switch_mutex_unlock(context->audio_mutex);
|
switch_mutex_unlock(context->audio_mutex);
|
||||||
handle->sample_count += *len;
|
handle->sample_count += *len;
|
||||||
|
|
||||||
return SWITCH_STATUS_SUCCESS;
|
return SWITCH_STATUS_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1059,8 +1182,8 @@ static void launch_thread(const char *name, const char *path, switch_xml_t direc
|
||||||
}
|
}
|
||||||
|
|
||||||
source->samples = switch_samples_per_packet(source->rate, source->interval);
|
source->samples = switch_samples_per_packet(source->rate, source->interval);
|
||||||
source->abuflen = (source->samples * 2 * source->channels) + 1024;
|
source->abuflen = (source->samples * 2 * source->channels);
|
||||||
source->abuf = switch_core_alloc(source->pool, source->abuflen);
|
source->abuf = switch_core_alloc(source->pool, source->abuflen + 1024);
|
||||||
switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool);
|
switch_mutex_init(&source->mutex, SWITCH_MUTEX_NESTED, source->pool);
|
||||||
switch_threadattr_create(&thd_attr, source->pool);
|
switch_threadattr_create(&thd_attr, source->pool);
|
||||||
switch_threadattr_detach_set(thd_attr, 1);
|
switch_threadattr_detach_set(thd_attr, 1);
|
||||||
|
|
|
@ -782,6 +782,13 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
|
||||||
|
|
||||||
switch_resample_destroy(&fh->resampler);
|
switch_resample_destroy(&fh->resampler);
|
||||||
|
|
||||||
|
if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
|
||||||
|
switch_core_destroy_memory_pool(&fh->memory_pool);
|
||||||
|
}
|
||||||
|
|
||||||
|
fh->memory_pool = NULL;
|
||||||
|
|
||||||
|
switch_safe_free(fh->dbuf);
|
||||||
|
|
||||||
if (fh->spool_path) {
|
if (fh->spool_path) {
|
||||||
char *command;
|
char *command;
|
||||||
|
@ -799,16 +806,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh)
|
||||||
free(command);
|
free(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
UNPROTECT_INTERFACE(fh->file_interface);
|
UNPROTECT_INTERFACE(fh->file_interface);
|
||||||
|
|
||||||
if (switch_test_flag(fh, SWITCH_FILE_FLAG_FREE_POOL)) {
|
|
||||||
switch_core_destroy_memory_pool(&fh->memory_pool);
|
|
||||||
}
|
|
||||||
|
|
||||||
switch_safe_free(fh->dbuf);
|
|
||||||
|
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue