From 5b509a72ef521cb8ffacff790acd814785dba9f7 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 2 Mar 2015 18:05:59 -0600 Subject: [PATCH] FS-7505: train video a little in beginning and make play file wait for it to train --- src/mod/formats/mod_vlc/mod_vlc.c | 19 +++---- src/switch_core_file.c | 2 +- src/switch_core_media.c | 83 +++++++++++++++++++++---------- src/switch_ivr_play_say.c | 16 ++++-- 4 files changed, 82 insertions(+), 38 deletions(-) diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index 3a3894b8fe..26b7d4065f 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -930,10 +930,6 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data } switch_mutex_unlock(vcontext->cond_mutex); } - - while(!switch_buffer_inuse(vcontext->audio_buffer) && !vcontext->err && vcontext->playing) { - switch_cond_next(); - } switch_mutex_lock(vcontext->audio_mutex); read = switch_buffer_read(vcontext->audio_buffer, data, bytes); @@ -944,7 +940,7 @@ static switch_status_t vlc_file_av_read(switch_file_handle_t *handle, void *data if (!read && (status == libvlc_Stopped || status == libvlc_Ended || status == libvlc_Error)) { return SWITCH_STATUS_FALSE; } else if (!read) { - read = 2; + read = bytes; memset(data, 0, read); } @@ -1030,6 +1026,11 @@ static switch_status_t vlc_file_read_video(switch_file_handle_t *handle, switch_ } if (switch_queue_pop(vcontext->video_queue, &pop) == SWITCH_STATUS_SUCCESS) { + if (!pop) { + vcontext->err = 1; + return SWITCH_STATUS_FALSE; + } + if (!vcontext->vid_ready) { vcontext->vid_ready = 1; @@ -1039,10 +1040,7 @@ static switch_status_t vlc_file_read_video(switch_file_handle_t *handle, switch_ } } - if (!pop) { - vcontext->err = 1; - return SWITCH_STATUS_FALSE; - } + frame->img = (switch_image_t *) pop; return SWITCH_STATUS_SUCCESS; } @@ -1378,6 +1376,9 @@ SWITCH_STANDARD_APP(play_video_function) libvlc_video_set_format_callbacks(context->mp, video_format_setup_callback, video_format_clean_callback); libvlc_video_set_callbacks(context->mp, vlc_video_lock_callback, vlc_video_unlock_callback, vlc_video_display_callback, context); + switch_channel_set_flag(channel, CF_VIDEO_DECODED_READ); + switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL); + // start play if (-1 == libvlc_media_player_play(context->mp)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "VLC error playing %s\n", path); diff --git a/src/switch_core_file.c b/src/switch_core_file.c index ab07c10dae..2f180bc7bb 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -222,7 +222,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_perform_file_open(const char *file, } } - if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO) && (flags & SWITCH_FILE_FLAG_WRITE)) { + if (switch_test_flag(fh, SWITCH_FILE_FLAG_VIDEO)) { fh->pre_buffer_datalen = 0; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 422ee3e080..392619fa7f 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -72,6 +72,7 @@ struct media_helper { switch_core_session_t *session; switch_thread_cond_t *cond; switch_mutex_t *cond_mutex; + switch_mutex_t *file_mutex; int up; }; @@ -4604,6 +4605,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses return SWITCH_STATUS_FALSE; } + switch_mutex_lock(v_engine->mh.file_mutex); + if (rw == SWITCH_RW_READ) { smh->video_read_fh = fh; if (fh) { @@ -4616,6 +4619,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses smh->video_write_fh = fh; } + switch_mutex_unlock(v_engine->mh.file_mutex); + return SWITCH_STATUS_SUCCESS; } @@ -4627,15 +4632,22 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi switch_status_t status; switch_frame_t *read_frame; switch_media_handle_t *smh; - uint32_t loops = 0, xloops = 0; + uint32_t loops = 0, xloops = 0, vloops = 0; switch_frame_t fr = { 0 }; unsigned char *buf = NULL; - //switch_rtp_engine_t *v_engine = NULL; + switch_image_t *blank_img = NULL; + switch_rgb_color_t bgcolor; + switch_color_set_rgb(&bgcolor, "#000000"); + blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, 640, 480, 1); + switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor); + + //switch_rtp_engine_t *v_engine = NULL; + if (!(smh = session->media_handle)) { return NULL; } - + //v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; switch_core_session_read_lock(session); @@ -4713,38 +4725,58 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi } if (read_frame->img) { - switch_channel_set_flag(channel, CF_VIDEO_READY); - smh->vid_params.width = read_frame->img->d_w; - smh->vid_params.height = read_frame->img->d_h; - } else if (read_frame->datalen > 2 && !switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) { + if (++vloops > 5) { + switch_channel_set_flag(channel, CF_VIDEO_READY); + smh->vid_params.width = read_frame->img->d_w; + smh->vid_params.height = read_frame->img->d_h; + } else { + switch_img_free(&blank_img); + blank_img = switch_img_alloc(NULL, SWITCH_IMG_FMT_I420, read_frame->img->d_w, read_frame->img->d_h, 1); + switch_img_fill(blank_img, 0, 0, blank_img->d_w, blank_img->d_h, &bgcolor); + } + } else if (read_frame->datalen > 2 && !switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) && ++vloops > 20) { switch_channel_set_flag(channel, CF_VIDEO_READY); } } - if (smh->video_write_fh) { - if (!buf) { - int buflen = SWITCH_RECOMMENDED_BUFFER_SIZE * 4; - buf = switch_core_session_alloc(session, buflen); - fr.packet = buf; - fr.packetlen = buflen; - fr.data = buf + 12; - fr.buflen = buflen - 12; - } - - if (switch_core_file_read_video(smh->video_write_fh, &fr) == SWITCH_STATUS_SUCCESS) { - switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0); - switch_img_free(&fr.img); - } + if (!buf) { + int buflen = SWITCH_RECOMMENDED_BUFFER_SIZE * 4; + buf = switch_core_session_alloc(session, buflen); + fr.packet = buf; + fr.packetlen = buflen; + fr.data = buf + 12; + fr.buflen = buflen - 12; + switch_core_media_gen_key_frame(session); + } - } else if (smh->video_read_fh && read_frame->img) { - switch_core_file_write_video(smh->video_read_fh, read_frame); - } + if (switch_channel_test_flag(channel, CF_VIDEO_READY)) { + switch_mutex_lock(mh->file_mutex); + if (smh->video_write_fh) { + switch_core_media_gen_key_frame(session); + while (smh->video_write_fh && + switch_channel_ready(session->channel) && switch_core_file_read_video(smh->video_write_fh, &fr) == SWITCH_STATUS_SUCCESS) { + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0); + switch_img_free(&fr.img); + switch_mutex_unlock(mh->file_mutex); + switch_mutex_lock(mh->file_mutex); + } + + } else if (smh->video_read_fh && read_frame->img) { + switch_core_file_write_video(smh->video_read_fh, read_frame); + } + switch_mutex_unlock(mh->file_mutex); + } else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ)) { + fr.img = blank_img; + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, 0); + } - if (read_frame && switch_channel_test_flag(channel, CF_VIDEO_ECHO)) { + if (read_frame && (switch_channel_test_flag(channel, CF_VIDEO_ECHO))) { switch_core_session_write_video_frame(session, read_frame, SWITCH_IO_FLAG_NONE, 0); } } + switch_img_free(&blank_img); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s Video thread ended\n", switch_channel_get_name(session->channel)); switch_mutex_unlock(mh->cond_mutex); @@ -4783,6 +4815,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_start_video_thread(switch_co switch_thread_cond_create(&v_engine->mh.cond, pool); switch_mutex_init(&v_engine->mh.cond_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&v_engine->mh.file_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&v_engine->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool); switch_thread_create(&v_engine->media_thread, thd_attr, video_helper_thread, &v_engine->mh, switch_core_session_get_pool(session)); diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index f2a3204a2b..bd37589b68 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -525,6 +525,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (switch_channel_test_flag(channel, CF_VIDEO)) { file_flags |= SWITCH_FILE_FLAG_VIDEO; + switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ); + switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL); } if (switch_core_file_open(fh, file, fh->channels, read_impl.actual_samples_per_second, file_flags, NULL) != SWITCH_STATUS_SUCCESS) { @@ -606,7 +608,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se "Raw Codec Activation Failed %s@%uhz %u channels %dms\n", codec_name, fh->samplerate, fh->channels, read_impl.microseconds_per_packet / 1000); if (switch_core_file_has_video(fh)) { - switch_channel_set_flag(channel, CF_VIDEO_ECHO); + switch_channel_clear_flag(channel, CF_VIDEO_ECHO); + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ); } switch_core_file_close(fh); @@ -782,7 +785,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } if (switch_core_file_has_video(fh)) { - switch_channel_set_flag(channel, CF_VIDEO_ECHO); + switch_channel_clear_flag(channel, CF_VIDEO_ECHO); + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_READ); } switch_core_file_close(fh); @@ -1259,6 +1263,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess if (switch_channel_test_flag(channel, CF_VIDEO)) { flags |= SWITCH_FILE_FLAG_VIDEO; + switch_channel_set_flag_recursive(channel, CF_VIDEO_DECODED_READ); + switch_channel_wait_for_flag(channel, CF_VIDEO_READY, SWITCH_TRUE, 10000, NULL); } if (switch_core_file_open(fh, @@ -1352,6 +1358,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_core_session_io_rwunlock(session); if (switch_core_file_has_video(fh)) { + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); } @@ -1377,6 +1384,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_core_session_io_rwunlock(session); if (switch_core_file_has_video(fh)) { + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); } switch_core_file_close(fh); @@ -1405,6 +1413,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_channel_set_private(channel, "__fh", NULL); switch_core_session_io_rwunlock(session); if (switch_core_file_has_video(fh)) { + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); } switch_core_file_close(fh); @@ -1565,7 +1574,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess olen /= 2; } switch_set_flag(fh, SWITCH_FILE_BREAK_ON_CHANGE); - + if ((rstatus = switch_core_file_read(fh, abuf, &olen)) == SWITCH_STATUS_BREAK) { continue; } @@ -1815,6 +1824,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_core_session_io_rwunlock(session); if (switch_core_file_has_video(fh)) { + switch_channel_clear_flag_recursive(channel, CF_VIDEO_DECODED_READ); switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); } switch_core_file_close(fh);