From abd9867cf9230df85a049ee3f04289d07cf563b8 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 3 Apr 2015 12:08:06 -0500 Subject: [PATCH] FS-7514: tweak vlc to ask for aac in mp4 don't start playing until the first read in vlc vid handles use correct buffer len Fixing typo. memset should zero out the whole struct add some mutexes fix locking issue on bad formatted input string --- src/mod/formats/mod_vlc/mod_vlc.c | 51 ++++++++++++++++++++----------- 1 file changed, 33 insertions(+), 18 deletions(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index a0313a4703..44e36ab295 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -119,7 +119,7 @@ struct vlc_video_context { switch_channel_t *channel; switch_frame_t *aud_frame; switch_frame_t *vid_frame; - uint8_t video_packet[SWITCH_RECOMMENDED_BUFFER_SIZE]; + uint8_t video_packet[SWITCH_RTP_MAX_BUF_LEN]; void *raw_yuyv_data; switch_image_t *img; switch_payload_t pt; @@ -277,19 +277,19 @@ static void vlc_media_av_state_callback(const libvlc_event_t * event, void * dat } switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a libvlc_MediaStateChanged callback. New state: %d\n", new_state); - - if (switch_mutex_lock(acontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { - switch_thread_cond_signal(acontext->cond); - switch_mutex_unlock(acontext->cond_mutex); - } - if ((new_state == 6 || new_state == 5) && vcontext->playing) { + if ((new_state == 6 || new_state == 5 || new_state == 7)) { vcontext->playing = 0; vcontext->err = 1; switch_queue_push(vcontext->video_queue, NULL); } - if (switch_mutex_lock(vcontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { + if (switch_mutex_trylock(acontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { + switch_thread_cond_signal(acontext->cond); + switch_mutex_unlock(acontext->cond_mutex); + } + + if (switch_mutex_trylock(vcontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { switch_thread_cond_signal(vcontext->cond); switch_mutex_unlock(vcontext->cond_mutex); } @@ -750,8 +750,6 @@ static switch_status_t vlc_file_av_open(switch_file_handle_t *handle, const char libvlc_video_set_format_callbacks(vcontext->mp, video_format_setup_callback, video_format_clean_callback); libvlc_video_set_callbacks(vcontext->mp, vlc_video_lock_callback, vlc_video_av_unlock_callback, vlc_video_display_callback, vcontext); - libvlc_media_player_play(vcontext->mp); - return SWITCH_STATUS_SUCCESS; } @@ -776,7 +774,7 @@ static switch_status_t vlc_file_open(switch_file_handle_t *handle, const char *p if (switch_test_flag(handle, SWITCH_FILE_FLAG_VIDEO) && switch_test_flag(handle, SWITCH_FILE_FLAG_WRITE)) { if ((ext = strrchr(path, '.')) && !strcasecmp(ext, ".mp4")) { realpath = path; - path = switch_core_sprintf(context->pool, "#transcode{vcodec=h264,acodec=mp3}:std{access=file,mux=mp4,dst=%s}", path); + path = switch_core_sprintf(context->pool, "#transcode{vcodec=h264,acodec=aac}:std{access=file,mux=mp4,dst=%s}", path); } else if (handle->stream_name && (!strcasecmp(handle->stream_name, "rtmp") || !strcasecmp(handle->stream_name, "youtube"))) { handle->mm.samplerate = 44100; @@ -976,6 +974,10 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data return SWITCH_STATUS_GENERR; } + if (!vcontext->playing) { + libvlc_media_player_play(vcontext->mp); + } + status = libvlc_media_get_state(vcontext->m); if (status == libvlc_Error) { @@ -1020,7 +1022,7 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data if (vcontext && vcontext->video_queue) { switch_queue_push(vcontext->video_queue, NULL); } - if (switch_mutex_lock(vcontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { + if (switch_mutex_trylock(vcontext->cond_mutex) == SWITCH_STATUS_SUCCESS) { switch_thread_cond_signal(vcontext->cond); switch_mutex_unlock(vcontext->cond_mutex); } @@ -1301,7 +1303,7 @@ static switch_status_t vlc_file_av_close(switch_file_handle_t *handle) switch_mutex_unlock(acontext->cond_mutex); } - while(switch_buffer_inuse(vcontext->audio_buffer) || switch_queue_size(vcontext->video_queue)) { + while((vcontext->audio_buffer && switch_buffer_inuse(vcontext->audio_buffer)) || switch_queue_size(vcontext->video_queue)) { libvlc_state_t status = libvlc_media_get_state(vcontext->m); if (status == libvlc_Ended || status == libvlc_Error || status == libvlc_Stopped ) { @@ -1325,9 +1327,11 @@ static switch_status_t vlc_file_av_close(switch_file_handle_t *handle) if (vcontext->timer.interval) switch_core_timer_destroy(&vcontext->timer); + switch_mutex_lock(vcontext->audio_mutex); if (vcontext->audio_buffer) { switch_buffer_destroy(&vcontext->audio_buffer); } + switch_mutex_unlock(vcontext->audio_mutex); return SWITCH_STATUS_SUCCESS; } @@ -1346,7 +1350,11 @@ static switch_status_t vlc_file_close(switch_file_handle_t *handle) libvlc_media_player_stop(context->mp); - switch_buffer_zero(context->audio_buffer); + switch_mutex_lock(context->audio_mutex); + if (context->audio_buffer) { + switch_buffer_zero(context->audio_buffer); + } + switch_mutex_unlock(context->audio_mutex); if (context->m) libvlc_media_release(context->m); @@ -1379,7 +1387,7 @@ SWITCH_STANDARD_APP(play_video_function) context = switch_core_session_alloc(session, sizeof(vlc_video_context_t)); switch_assert(context); - memset(context, 0, sizeof(vlc_file_context_t)); + memset(context, 0, sizeof(vlc_video_context_t)); if ((tmp = switch_channel_get_variable(channel, "vlc_force_width"))) { context->force_width = atoi(tmp); @@ -1534,6 +1542,7 @@ SWITCH_STANDARD_APP(play_video_function) } } + switch_mutex_lock(context->audio_mutex); if (switch_buffer_inuse(context->audio_buffer) >= audio_datalen) { const void *decoded_data; //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "%d %d\n", (int)switch_buffer_inuse(context->audio_buffer), (int)audio_datalen); @@ -1544,6 +1553,7 @@ SWITCH_STANDARD_APP(play_video_function) switch_core_session_write_frame(context->session, &audio_frame, SWITCH_IO_FLAG_NONE, 0); switch_buffer_toss(context->audio_buffer, audio_datalen); } + switch_mutex_unlock(context->audio_mutex); } @@ -1652,8 +1662,7 @@ int vlc_write_video_imem_get_callback(void *data, const char *cookie, int64_t * switch_mutex_unlock(context->audio_mutex); return 0; } - switch_mutex_unlock(context->audio_mutex); - + if ((blen = switch_buffer_inuse(context->audio_buffer))) { uint32_t read_bytes = 0; int64_t lpts; @@ -1944,6 +1953,7 @@ SWITCH_STANDARD_APP(capture_video_function) switch_mutex_unlock(context->cond_mutex); } + switch_mutex_lock(context->audio_mutex); while(switch_buffer_inuse(context->audio_buffer) || switch_queue_size(context->video_queue)) { libvlc_state_t status = libvlc_media_get_state(context->m); @@ -1954,6 +1964,7 @@ SWITCH_STANDARD_APP(capture_video_function) switch_yield(10000); } + switch_mutex_unlock(context->audio_mutex); context->playing = 0; @@ -1970,7 +1981,9 @@ SWITCH_STANDARD_APP(capture_video_function) } if (context->audio_buffer) { + switch_mutex_lock(context->audio_mutex); switch_buffer_destroy(&context->audio_buffer); + switch_mutex_unlock(context->audio_mutex); } switch_core_session_reset(session, SWITCH_TRUE, SWITCH_TRUE); @@ -2237,9 +2250,11 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) tech_pvt->context->playing = 0; + switch_mutex_lock(tech_pvt->context->audio_mutex); if (tech_pvt->context->audio_buffer) { switch_buffer_destroy(&tech_pvt->context->audio_buffer); } + switch_mutex_unlock(tech_pvt->context->audio_mutex); if (tech_pvt->context->video_queue) { void *pop; @@ -2447,7 +2462,7 @@ static switch_status_t vlc_read_frame(switch_core_session_t *session, switch_fra tech_pvt->read_frame.buflen = tech_pvt->audio_datalen; switch_mutex_lock(context->audio_mutex); - if (switch_buffer_inuse(context->audio_buffer) >= audio_datalen) { + if (context->audio_buffer && switch_buffer_inuse(context->audio_buffer) >= audio_datalen) { switch_buffer_read(context->audio_buffer, tech_pvt->audio_data, audio_datalen); } else { memset(tech_pvt->audio_data, 0, audio_datalen);