FS-7514: slow down vlc callback by syncing with video flow
This commit is contained in:
parent
af0f2e6ea8
commit
6b289ed02a
|
@ -79,7 +79,7 @@ struct vlc_file_context {
|
|||
switch_memory_pool_t *pool;
|
||||
switch_buffer_t *audio_buffer;
|
||||
switch_mutex_t *audio_mutex;
|
||||
switch_thread_cond_t *started;
|
||||
switch_thread_cond_t *cond;
|
||||
char *path;
|
||||
int samples;
|
||||
int playing;
|
||||
|
@ -100,11 +100,11 @@ struct vlc_video_context {
|
|||
switch_mutex_t *audio_mutex;
|
||||
switch_file_handle_t fh;
|
||||
switch_memory_pool_t *pool;
|
||||
switch_thread_cond_t *started;
|
||||
switch_thread_cond_t *cond;
|
||||
switch_buffer_t *audio_buffer;
|
||||
switch_queue_t *video_queue;
|
||||
int playing;
|
||||
|
||||
int ending;
|
||||
switch_mutex_t *video_mutex;
|
||||
|
||||
switch_core_session_t *session;
|
||||
|
@ -171,7 +171,7 @@ static void vlc_mediaplayer_error_callback(const libvlc_event_t * event, void *
|
|||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a libvlc_MediaPlayerEncounteredError callback. mediaPlayer Status: %d\n", status);
|
||||
if (status == libvlc_Error) {
|
||||
context->err = 1;
|
||||
switch_thread_cond_signal(context->started);
|
||||
switch_thread_cond_signal(context->cond);
|
||||
}
|
||||
}
|
||||
static void vlc_media_state_callback(const libvlc_event_t * event, void * data)
|
||||
|
@ -181,7 +181,7 @@ static void vlc_media_state_callback(const libvlc_event_t * event, void * data)
|
|||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a libvlc_MediaStateChanged callback. New state: %d\n", new_state);
|
||||
if (new_state == libvlc_Ended || new_state == libvlc_Error) {
|
||||
switch_thread_cond_signal(context->started);
|
||||
switch_thread_cond_signal(context->cond);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -200,7 +200,7 @@ void vlc_auto_play_callback(void *data, const void *samples, unsigned count, int
|
|||
|
||||
if(!context->playing ) {
|
||||
context->playing = 1;
|
||||
switch_thread_cond_signal(context->started);
|
||||
switch_thread_cond_signal(context->cond);
|
||||
}
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
}
|
||||
|
@ -223,7 +223,7 @@ void vlc_play_audio_callback(void *data, const void *samples, unsigned count, in
|
|||
|
||||
if (!context->playing) {
|
||||
context->playing = 1;
|
||||
if (context->started) switch_thread_cond_signal(context->started);
|
||||
if (context->cond) switch_thread_cond_signal(context->cond);
|
||||
}
|
||||
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
|
@ -407,7 +407,7 @@ static switch_status_t vlc_file_open(switch_file_handle_t *handle, const char *p
|
|||
|
||||
switch_buffer_create_dynamic(&(context->audio_buffer), VLC_BUFFER_SIZE, VLC_BUFFER_SIZE * 8, 0);
|
||||
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||
switch_thread_cond_create(&(context->started), context->pool);
|
||||
switch_thread_cond_create(&(context->cond), context->pool);
|
||||
|
||||
if (switch_test_flag(handle, SWITCH_FILE_FLAG_READ)) {
|
||||
|
||||
|
@ -531,7 +531,7 @@ static switch_status_t vlc_file_read(switch_file_handle_t *handle, void *data, s
|
|||
|
||||
switch_mutex_lock(context->audio_mutex);
|
||||
while (context->playing == 0 && status != libvlc_Ended && status != libvlc_Error) {
|
||||
switch_thread_cond_wait(context->started, context->audio_mutex);
|
||||
switch_thread_cond_wait(context->cond, context->audio_mutex);
|
||||
status = libvlc_media_get_state(context->m);
|
||||
}
|
||||
|
||||
|
@ -679,7 +679,7 @@ SWITCH_STANDARD_APP(play_video_function)
|
|||
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||
switch_mutex_init(&context->video_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||
|
||||
switch_thread_cond_create(&(context->started), context->pool);
|
||||
switch_thread_cond_create(&(context->cond), context->pool);
|
||||
|
||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "VLC open %s for reading\n", path);
|
||||
|
||||
|
@ -812,14 +812,12 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t *
|
|||
int bytes = 0, bread = 0, blen = 0;
|
||||
int r = 0;
|
||||
|
||||
|
||||
switch_mutex_lock(context->audio_mutex);
|
||||
|
||||
if (!switch_channel_ready(context->channel)) {
|
||||
if (!switch_buffer_inuse(context->audio_buffer) && switch_queue_size(context->video_queue) == 0) {
|
||||
r = -1;
|
||||
goto nada;
|
||||
if (!context->ending) {
|
||||
switch_mutex_lock(context->video_mutex);
|
||||
if (!switch_queue_size(context->video_queue)) {
|
||||
switch_thread_cond_wait(context->cond, context->video_mutex);
|
||||
}
|
||||
switch_mutex_unlock(context->video_mutex);
|
||||
}
|
||||
|
||||
if (*cookie == 'v') {
|
||||
|
@ -849,10 +847,11 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t *
|
|||
switch_img_convert(img, SWITCH_CONVERT_FMT_YUYV, *output, size);
|
||||
switch_img_free(&img);
|
||||
|
||||
goto ok;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
switch_mutex_lock(context->audio_mutex);
|
||||
|
||||
if ((blen = switch_buffer_inuse(context->audio_buffer))) {
|
||||
switch_buffer_read(context->audio_buffer, &context->pts, sizeof(context->pts));
|
||||
blen = switch_buffer_inuse(context->audio_buffer);
|
||||
|
@ -860,6 +859,7 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t *
|
|||
}
|
||||
|
||||
if (!(bytes = blen)) {
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
goto nada;
|
||||
}
|
||||
|
||||
|
@ -874,28 +874,24 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t *
|
|||
|
||||
*size = (size_t) bread;
|
||||
|
||||
//printf("A SIZE %ld ts %ld %p\n", *size, *pts, (void *)pthread_self());
|
||||
|
||||
ok:
|
||||
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
|
||||
return 0;
|
||||
|
||||
nada:
|
||||
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
|
||||
if (!switch_channel_ready(context->channel)) {
|
||||
if (!switch_buffer_inuse(context->audio_buffer) && switch_queue_size(context->video_queue) == 0) {
|
||||
r = -1;
|
||||
if (context->ending) {
|
||||
if (*cookie == 'a') {
|
||||
if (!switch_buffer_inuse(context->audio_buffer)) {
|
||||
r = -1;
|
||||
}
|
||||
} else {
|
||||
if (switch_queue_size(context->video_queue) == 0) {
|
||||
r = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//printf("nada %s\n", cookie);
|
||||
|
||||
//switch_core_timer_sync(&context->timer);
|
||||
*dts = *pts = 0;
|
||||
|
||||
*size = 0;
|
||||
*output = NULL;
|
||||
|
||||
|
@ -914,16 +910,28 @@ static switch_status_t video_read_callback(switch_core_session_t *session, switc
|
|||
vlc_frame_data_t *fdata = NULL;
|
||||
|
||||
if (frame->img) {
|
||||
unsigned int size = switch_queue_size(context->video_queue);
|
||||
|
||||
switch_img_copy(frame->img, &img_copy);
|
||||
switch_zmalloc(fdata, sizeof(*fdata));
|
||||
|
||||
switch_mutex_lock(context->audio_mutex);
|
||||
switch_core_timer_sync(&context->timer);
|
||||
fdata->pts = context->timer.samplecount;
|
||||
switch_mutex_unlock(context->audio_mutex);
|
||||
|
||||
img_copy->user_priv = (void *) fdata;
|
||||
switch_queue_push(context->video_queue, img_copy);
|
||||
|
||||
if (!size) { /* was empty before this push */
|
||||
if (switch_mutex_trylock(context->video_mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_thread_cond_signal(context->cond);
|
||||
switch_mutex_unlock(context->video_mutex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return SWITCH_STATUS_SUCCESS;
|
||||
|
||||
}
|
||||
|
@ -992,6 +1000,7 @@ SWITCH_STANDARD_APP(capture_video_function)
|
|||
switch_buffer_create_dynamic(&(context->audio_buffer), VLC_BUFFER_SIZE, VLC_BUFFER_SIZE * 8, 0);
|
||||
switch_mutex_init(&context->audio_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||
switch_mutex_init(&context->video_mutex, SWITCH_MUTEX_NESTED, context->pool);
|
||||
switch_thread_cond_create(&context->cond, context->pool);
|
||||
|
||||
switch_core_timer_init(&context->timer, "soft", 1, 1000, context->pool);
|
||||
|
||||
|
@ -1106,7 +1115,15 @@ SWITCH_STANDARD_APP(capture_video_function)
|
|||
}
|
||||
}
|
||||
|
||||
while(switch_buffer_inuse(context->audio_buffer)) {
|
||||
switch_core_session_set_video_read_callback(session, NULL, NULL);
|
||||
context->ending = 1;
|
||||
|
||||
if (switch_mutex_trylock(context->video_mutex) == SWITCH_STATUS_SUCCESS) {
|
||||
switch_thread_cond_signal(context->cond);
|
||||
switch_mutex_unlock(context->video_mutex);
|
||||
}
|
||||
|
||||
while(switch_buffer_inuse(context->audio_buffer) || switch_queue_size(context->video_queue)) {
|
||||
libvlc_state_t status = libvlc_media_get_state(context->m);
|
||||
|
||||
if (status == libvlc_Ended || status == libvlc_Error || status == libvlc_Stopped ) {
|
||||
|
@ -1118,7 +1135,7 @@ SWITCH_STANDARD_APP(capture_video_function)
|
|||
}
|
||||
|
||||
context->playing = 0;
|
||||
switch_core_session_set_video_read_callback(session, NULL, NULL);
|
||||
|
||||
|
||||
if (context->mp) libvlc_media_player_stop(context->mp);
|
||||
if (context->m) libvlc_media_release(context->m);
|
||||
|
|
Loading…
Reference in New Issue