From b7227465b6943588bf7d1a1e61e0fcc829d6f43e Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Mon, 7 Mar 2016 19:59:03 -0600 Subject: [PATCH] FS-8909 #resolve [Add feature to play background video while recording inbound video] --- src/include/switch_core.h | 2 + src/include/switch_core_media.h | 2 + src/include/switch_module_interfaces.h | 2 + src/include/switch_types.h | 7 +- src/mod/applications/mod_av/avformat.c | 23 ++++- src/mod/formats/mod_vlc/mod_vlc.c | 18 ++++ src/switch_core_file.c | 31 ++++++ src/switch_core_media.c | 126 +++++++++++++++++++------ src/switch_ivr_play_say.c | 99 ++++++++++++++++--- 9 files changed, 264 insertions(+), 46 deletions(-) diff --git a/src/include/switch_core.h b/src/include/switch_core.h index 8014e95eae..552ea1c621 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1929,6 +1929,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_get_string(_In_ switch_file_han */ SWITCH_DECLARE(switch_status_t) switch_core_file_close(_In_ switch_file_handle_t *fh); +SWITCH_DECLARE(switch_status_t) switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command); + SWITCH_DECLARE(switch_status_t) switch_core_file_truncate(switch_file_handle_t *fh, int64_t offset); SWITCH_DECLARE(switch_bool_t) switch_core_file_has_video(switch_file_handle_t *fh); diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 4528da03c8..65c400ea33 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -340,6 +340,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_read_lock_unlock(switch_core_s SWITCH_DECLARE(void) switch_core_session_stop_media(switch_core_session_t *session); SWITCH_DECLARE(switch_media_flow_t) switch_core_session_media_flow(switch_core_session_t *session, switch_media_type_t type); SWITCH_DECLARE(switch_status_t) switch_core_media_get_vid_params(switch_core_session_t *session, switch_vid_params_t *vid_params); +SWITCH_DECLARE(switch_status_t) switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw); +SWITCH_DECLARE(switch_status_t) switch_core_media_unlock_video_file(switch_core_session_t *session, switch_rw_t rw); SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw); SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_core_session_t *session, switch_rw_t rw); SWITCH_DECLARE(switch_bool_t) switch_core_session_in_video_thread(switch_core_session_t *session); diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 8621e53d6f..4a3e8c71f8 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -289,6 +289,8 @@ struct switch_file_interface { switch_status_t (*file_set_string) (switch_file_handle_t *fh, switch_audio_col_t col, const char *string); /*! function to get meta data */ switch_status_t (*file_get_string) (switch_file_handle_t *fh, switch_audio_col_t col, const char **string); + /*! function to control the underlying tech of the file */ + switch_status_t (*file_command) (switch_file_handle_t *fh, switch_file_command_t command); /*! list of supported file extensions */ char **extens; switch_thread_rwlock_t *rwlock; diff --git a/src/include/switch_types.h b/src/include/switch_types.h index d149fb60c0..31f4ebfc31 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1811,7 +1811,8 @@ typedef enum { SWITCH_FILE_WRITE_OVER = (1 << 16), SWITCH_FILE_NOMUX = (1 << 17), SWITCH_FILE_BREAK_ON_CHANGE = (1 << 18), - SWITCH_FILE_FLAG_VIDEO = (1 << 19) + SWITCH_FILE_FLAG_VIDEO = (1 << 19), + SWITCH_FILE_FLAG_VIDEO_EOF = (1 << 20) } switch_file_flag_enum_t; typedef uint32_t switch_file_flag_t; @@ -2595,6 +2596,10 @@ typedef enum { SPY_DUAL_CROP } switch_vid_spy_fmt_t; +typedef enum { + SCFC_FLUSH_AUDIO +} switch_file_command_t; + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/applications/mod_av/avformat.c b/src/mod/applications/mod_av/avformat.c index a5faa2e4bc..190a23456f 100644 --- a/src/mod/applications/mod_av/avformat.c +++ b/src/mod/applications/mod_av/avformat.c @@ -1770,6 +1770,23 @@ static switch_status_t av_file_write(switch_file_handle_t *handle, void *data, s return status; } +static switch_status_t av_file_command(switch_file_handle_t *handle, switch_file_command_t command) +{ + av_file_context_t *context = (av_file_context_t *)handle->private_info; + + switch(command) { + case SCFC_FLUSH_AUDIO: + switch_mutex_lock(context->mutex); + switch_buffer_zero(context->audio_buffer); + switch_mutex_unlock(context->mutex); + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t av_file_close(switch_file_handle_t *handle) { av_file_context_t *context = (av_file_context_t *)handle->private_info; @@ -1840,9 +1857,8 @@ static switch_status_t av_file_read(switch_file_handle_t *handle, void *data, si } switch_mutex_lock(context->mutex); - size = switch_buffer_inuse(context->audio_buffer); - if (size > *len * context->audio_st.channels * 2) size = *len * context->audio_st.channels * 2; - if (size) size = switch_buffer_read(context->audio_buffer, data, size); + + size = switch_buffer_read(context->audio_buffer, data, need); switch_mutex_unlock(context->mutex); if (size == 0) { @@ -2174,6 +2190,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_avformat_load) file_interface->file_seek = av_file_seek; file_interface->file_set_string = av_file_set_string; file_interface->file_get_string = av_file_get_string; + file_interface->file_command = av_file_command; SWITCH_ADD_API(api_interface, "av_format", "av information", av_format_api_function, ""); diff --git a/src/mod/formats/mod_vlc/mod_vlc.c b/src/mod/formats/mod_vlc/mod_vlc.c index e9769fc084..dbacf4e513 100644 --- a/src/mod/formats/mod_vlc/mod_vlc.c +++ b/src/mod/formats/mod_vlc/mod_vlc.c @@ -1340,6 +1340,23 @@ static switch_status_t vlc_file_av_close(switch_file_handle_t *handle) return SWITCH_STATUS_SUCCESS; } +static switch_status_t vlc_file_command(switch_file_handle_t *handle, switch_file_command_t command) +{ + vlc_file_context_t *context = handle->private_info; + + switch(command) { + case SCFC_FLUSH_AUDIO: + switch_mutex_lock(context->audio_mutex); + switch_buffer_zero(context->audio_buffer); + switch_mutex_unlock(context->audio_mutex); + break; + default: + break; + } + + return SWITCH_STATUS_SUCCESS; +} + static switch_status_t vlc_file_close(switch_file_handle_t *handle) { vlc_file_context_t *context = handle->private_info; @@ -2608,6 +2625,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_vlc_load) file_interface->extens = vlc_file_supported_formats; file_interface->file_open = vlc_file_open; file_interface->file_close = vlc_file_close; + file_interface->file_command = vlc_file_command; file_interface->file_read = vlc_file_read; file_interface->file_write = vlc_file_write; file_interface->file_read_video = vlc_file_read_video; diff --git a/src/switch_core_file.c b/src/switch_core_file.c index d2998b9907..fcc21e4491 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -735,6 +735,37 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_truncate(switch_file_handle_t * } +SWITCH_DECLARE(switch_status_t) switch_core_file_command(switch_file_handle_t *fh, switch_file_command_t command) +{ + switch_status_t status = SWITCH_STATUS_FALSE; + + switch_assert(fh != NULL); + switch_assert(fh->file_interface != NULL); + + if (!switch_test_flag(fh, SWITCH_FILE_OPEN)) { + return SWITCH_STATUS_FALSE; + } + + switch(command) { + case SCFC_FLUSH_AUDIO: + if (fh->pre_buffer) { + switch_buffer_zero(fh->pre_buffer); + } + break; + default: + break; + } + + if (fh->file_interface->file_command) { + switch_mutex_lock(fh->flag_mutex); + status = fh->file_interface->file_command(fh, command); + switch_mutex_unlock(fh->flag_mutex); + } + + return status; +} + + SWITCH_DECLARE(switch_status_t) switch_core_file_close(switch_file_handle_t *fh) { switch_status_t status; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 9a61980f44..85bd05b944 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -80,7 +80,8 @@ struct media_helper { switch_core_session_t *session; switch_thread_cond_t *cond; switch_mutex_t *cond_mutex; - switch_mutex_t *file_mutex; + switch_mutex_t *file_read_mutex; + switch_mutex_t *file_write_mutex; int up; }; @@ -4952,15 +4953,19 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; - switch_mutex_lock(v_engine->mh.file_mutex); + if (rw == SWITCH_RW_READ) { + switch_mutex_lock(v_engine->mh.file_read_mutex); fh = smh->video_read_fh; + switch_mutex_unlock(v_engine->mh.file_read_mutex); } else { + switch_mutex_lock(v_engine->mh.file_write_mutex); fh = smh->video_write_fh; + switch_mutex_unlock(v_engine->mh.file_write_mutex); } - switch_mutex_unlock(v_engine->mh.file_mutex); + return fh; } @@ -5009,24 +5014,29 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session)); - while (smh->video_write_thread_running > 0 && + while (smh->video_write_thread_running > 0 && switch_channel_up_nosig(session->channel) && smh->video_write_fh && switch_test_flag(smh->video_write_fh, SWITCH_FILE_OPEN)) { switch_status_t wstatus = SWITCH_STATUS_FALSE; switch_core_timer_next(&timer); - switch_mutex_lock(v_engine->mh.file_mutex); + switch_mutex_lock(v_engine->mh.file_write_mutex); - if (smh->video_write_fh) { + if (smh->video_write_fh->mm.source_fps && smh->video_write_fh->mm.source_fps != fps) { + switch_core_timer_destroy(&timer); + switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , 1, switch_core_session_get_pool(session)); + } + + if (smh->video_write_fh && !switch_test_flag(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF)) { wstatus = switch_core_file_read_video(smh->video_write_fh, &fr, SVR_BLOCK); - } - if (wstatus == SWITCH_STATUS_SUCCESS) { - switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, SVR_FLUSH); - switch_img_free(&fr.img); - } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { - smh->video_write_fh = NULL; + if (wstatus == SWITCH_STATUS_SUCCESS) { + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_NONE, SVR_FLUSH); + switch_img_free(&fr.img); + } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { + switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF); + } } - switch_mutex_unlock(v_engine->mh.file_mutex); + switch_mutex_unlock(v_engine->mh.file_write_mutex); } switch_core_timer_destroy(&timer); @@ -5038,6 +5048,59 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void return NULL; } +SWITCH_DECLARE(switch_status_t) switch_core_media_lock_video_file(switch_core_session_t *session, switch_rw_t rw) +{ + switch_media_handle_t *smh; + switch_rtp_engine_t *v_engine; + + switch_assert(session); + + if (!switch_channel_test_flag(session->channel, CF_VIDEO)) { + return SWITCH_STATUS_FALSE; + } + + if (!(smh = session->media_handle)) { + return SWITCH_STATUS_FALSE; + } + + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + + if (rw == SWITCH_RW_READ) { + switch_mutex_lock(v_engine->mh.file_read_mutex); + } else { + switch_mutex_lock(v_engine->mh.file_write_mutex); + } + + return SWITCH_STATUS_SUCCESS; + +} + +SWITCH_DECLARE(switch_status_t) switch_core_media_unlock_video_file(switch_core_session_t *session, switch_rw_t rw) +{ + switch_media_handle_t *smh; + switch_rtp_engine_t *v_engine; + + switch_assert(session); + + if (!switch_channel_test_flag(session->channel, CF_VIDEO)) { + return SWITCH_STATUS_FALSE; + } + + if (!(smh = session->media_handle)) { + return SWITCH_STATUS_FALSE; + } + + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + + if (rw == SWITCH_RW_READ) { + switch_mutex_unlock(v_engine->mh.file_read_mutex); + } else { + switch_mutex_unlock(v_engine->mh.file_write_mutex); + } + + return SWITCH_STATUS_SUCCESS; +} + SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_session_t *session, switch_file_handle_t *fh, switch_rw_t rw) { switch_media_handle_t *smh; @@ -5061,13 +5124,14 @@ 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) { + switch_mutex_lock(v_engine->mh.file_read_mutex); if (fh && smh->video_read_fh) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File is already open\n"); - switch_mutex_unlock(v_engine->mh.file_mutex); + switch_mutex_unlock(v_engine->mh.file_read_mutex); return SWITCH_STATUS_FALSE; } @@ -5086,12 +5150,16 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses smh->video_read_fh = fh; + switch_mutex_unlock(v_engine->mh.file_read_mutex); + } else { + switch_mutex_lock(v_engine->mh.file_write_mutex); if (fh && smh->video_write_fh) { - switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File is already open\n"); - switch_mutex_unlock(v_engine->mh.file_mutex); - return SWITCH_STATUS_FALSE; + //switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "File is already open\n"); + smh->video_write_fh = fh; + switch_mutex_unlock(v_engine->mh.file_write_mutex); + return SWITCH_STATUS_SUCCESS; } if (fh) { @@ -5111,23 +5179,26 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses switch_thread_create(&smh->video_write_thread, thd_attr, video_write_thread, session, switch_core_session_get_pool(session)); } - smh->video_write_fh = fh; - if (!fh && smh->video_write_thread) { switch_status_t st; - smh->video_write_thread_running = -1; - switch_mutex_unlock(v_engine->mh.file_mutex); + if (smh->video_write_thread_running > 0) { + smh->video_write_thread_running = -1; + } + switch_mutex_unlock(v_engine->mh.file_write_mutex); switch_thread_join(&st, smh->video_write_thread); - switch_mutex_lock(v_engine->mh.file_mutex); + switch_mutex_lock(v_engine->mh.file_write_mutex); smh->video_write_thread = NULL; } + smh->video_write_fh = fh; + + switch_mutex_unlock(v_engine->mh.file_write_mutex); } if (!fh) switch_channel_video_sync(session->channel); switch_core_session_wake_video_thread(session); - switch_mutex_unlock(v_engine->mh.file_mutex); + return SWITCH_STATUS_SUCCESS; } @@ -5289,12 +5360,12 @@ static void *SWITCH_THREAD_FUNC video_helper_thread(switch_thread_t *thread, voi if (switch_channel_test_flag(channel, CF_VIDEO_READY)) { - switch_mutex_lock(mh->file_mutex); + switch_mutex_lock(mh->file_read_mutex); if (smh->video_read_fh && switch_test_flag(smh->video_read_fh, SWITCH_FILE_OPEN) && read_frame->img) { switch_core_file_write_video(smh->video_read_fh, read_frame); send_blank = 0; } - switch_mutex_unlock(mh->file_mutex); + switch_mutex_unlock(mh->file_read_mutex); } else if (switch_channel_test_flag(channel, CF_VIDEO_DECODED_READ) || v_engine->smode == SWITCH_MEDIA_FLOW_SENDONLY) { send_blank = 1; } @@ -5355,7 +5426,8 @@ 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->mh.file_read_mutex, SWITCH_MUTEX_NESTED, pool); + switch_mutex_init(&v_engine->mh.file_write_mutex, SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&smh->read_mutex[SWITCH_MEDIA_TYPE_VIDEO], SWITCH_MUTEX_NESTED, pool); switch_mutex_init(&smh->write_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 023f6add41..9be39f1fd7 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -359,6 +359,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_channel_t *channel = switch_core_session_get_channel(session); switch_dtmf_t dtmf = { 0 }; switch_file_handle_t lfh = { 0 }; + switch_file_handle_t vfh = { 0 }; switch_frame_t *read_frame; switch_codec_t codec, write_codec = { 0 }; char *codec_name; @@ -377,8 +378,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se int divisor = 0; int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; int restart_limit_on_dtmf = 0; - const char *prefix, *var; - + const char *prefix, *var, *video_file = NULL; + int vid_play_file_flags = SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO; + if (switch_channel_pre_answer(channel) != SWITCH_STATUS_SUCCESS) { return SWITCH_STATUS_FALSE; @@ -548,7 +550,34 @@ 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_core_session_request_video_refresh(session); + + if ((p = switch_channel_get_variable(channel, "record_play_video")) || + + (fh->params && (p = switch_event_get_header(fh->params, "record_play_video")))) { + + video_file = switch_core_session_strdup(session, p); + + if (switch_core_file_open(&vfh, video_file, fh->channels, + read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) { + memset(&vfh, 0, sizeof(vfh)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n"); + } + + if (switch_core_file_has_video(fh)) { + switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE); + switch_core_media_gen_key_frame(session); + } else { + switch_core_file_close(&vfh); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n"); + memset(&vfh, 0, sizeof(vfh)); + } + } + + if (!switch_test_flag(&vfh, SWITCH_FILE_OPEN)) { + switch_channel_set_flag(channel, CF_VIDEO_ECHO); + } + switch_core_media_set_video_file(session, fh, SWITCH_RW_READ); } else if (switch_channel_test_flag(channel, CF_VIDEO)) { switch_channel_set_flag(channel, CF_VIDEO_BLANK); @@ -568,42 +597,43 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")); - if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { + if ((p = switch_channel_get_variable(channel, "record_title")) || (fh->params && (p = switch_event_get_header(fh->params, "record_title")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_TITLE, vval); - switch_channel_set_variable(channel, "RECORD_TITLE", NULL); + switch_channel_set_variable(channel, "record_title", NULL); } - if ((p = switch_channel_get_variable(channel, "RECORD_COPYRIGHT"))) { + if ((p = switch_channel_get_variable(channel, "record_copyright")) || (fh->params && (p = switch_event_get_header(fh->params, "record_copyright")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COPYRIGHT, vval); - switch_channel_set_variable(channel, "RECORD_COPYRIGHT", NULL); + switch_channel_set_variable(channel, "record_copyright", NULL); } - if ((p = switch_channel_get_variable(channel, "RECORD_SOFTWARE"))) { + if ((p = switch_channel_get_variable(channel, "record_software")) || (fh->params && (p = switch_event_get_header(fh->params, "record_software")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_SOFTWARE, vval); - switch_channel_set_variable(channel, "RECORD_SOFTWARE", NULL); + switch_channel_set_variable(channel, "record_software", NULL); } - if ((p = switch_channel_get_variable(channel, "RECORD_ARTIST"))) { + if ((p = switch_channel_get_variable(channel, "record_artist")) || (fh->params && (p = switch_event_get_header(fh->params, "record_artist")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_ARTIST, vval); - switch_channel_set_variable(channel, "RECORD_ARTIST", NULL); + switch_channel_set_variable(channel, "record_artist", NULL); } - if ((p = switch_channel_get_variable(channel, "RECORD_COMMENT"))) { + if ((p = switch_channel_get_variable(channel, "record_comment")) || (fh->params && (p = switch_event_get_header(fh->params, "record_comment")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_COMMENT, vval); - switch_channel_set_variable(channel, "RECORD_COMMENT", NULL); + switch_channel_set_variable(channel, "record_comment", NULL); } - if ((p = switch_channel_get_variable(channel, "RECORD_DATE"))) { + if ((p = switch_channel_get_variable(channel, "record_date")) || (fh->params && (p = switch_event_get_header(fh->params, "record_date")))) { vval = switch_core_session_strdup(session, p); switch_core_file_set_string(fh, SWITCH_AUDIO_COL_STR_DATE, vval); - switch_channel_set_variable(channel, "RECORD_DATE", NULL); + switch_channel_set_variable(channel, "record_date", NULL); } + switch_channel_set_variable(channel, "silence_hits_exhausted", "false"); if (!asis) { @@ -627,6 +657,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se 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); + if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) { + switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); + } } switch_channel_clear_flag(channel, CF_VIDEO_BLANK); switch_core_file_close(fh); @@ -748,6 +781,39 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se } } + if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) { + switch_core_file_command(&vfh, SCFC_FLUSH_AUDIO); + + if (switch_test_flag(&vfh, SWITCH_FILE_FLAG_VIDEO_EOF)) { + + //switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); + + switch_core_media_lock_video_file(session, SWITCH_RW_WRITE); + + switch_core_file_close(&vfh); + memset(&vfh, 0, sizeof(vfh)); + + if (switch_core_file_open(&vfh, video_file, fh->channels, + read_impl.actual_samples_per_second, vid_play_file_flags, NULL) != SWITCH_STATUS_SUCCESS) { + memset(&vfh, 0, sizeof(vfh)); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Failure opening video playback file.\n"); + } + + if (switch_core_file_has_video(fh)) { + //switch_core_media_set_video_file(session, &vfh, SWITCH_RW_WRITE); + switch_core_media_gen_key_frame(session); + } else { + switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); + switch_core_file_close(&vfh); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Video playback file does not contain video\n"); + memset(&vfh, 0, sizeof(vfh)); + } + + switch_core_media_unlock_video_file(session, SWITCH_RW_WRITE); + } + + } + if (!asis && fh->thresh) { int16_t *fdata = (int16_t *) read_frame->data; uint32_t samples = read_frame->datalen / sizeof(*fdata); @@ -806,6 +872,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se 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); + if (switch_test_flag(&vfh, SWITCH_FILE_OPEN)) { + switch_core_media_set_video_file(session, NULL, SWITCH_RW_WRITE); + } } switch_channel_clear_flag(channel, CF_VIDEO_BLANK); switch_core_file_close(fh);