From 1c37daba4c3312a304c26ea7a90ff33c1c5e3648 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Fri, 19 Jul 2019 23:28:48 +0000 Subject: [PATCH] [mod_video_filter] fix some keyframe stuff and add read:sound and write:sound options --- .../mod_video_filter/mod_video_filter.c | 98 +++++++++++++++---- src/switch_ivr_async.c | 1 + 2 files changed, 80 insertions(+), 19 deletions(-) diff --git a/src/mod/applications/mod_video_filter/mod_video_filter.c b/src/mod/applications/mod_video_filter/mod_video_filter.c index 613f8d9195..2f4d5d5bf7 100644 --- a/src/mod/applications/mod_video_filter/mod_video_filter.c +++ b/src/mod/applications/mod_video_filter/mod_video_filter.c @@ -74,6 +74,7 @@ typedef struct video_replace_context_s { switch_image_t *rp_img; switch_file_handle_t vfh; switch_core_session_t *session; + int sound; } video_replace_context_t; @@ -227,7 +228,6 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char if (n > 2 && argv[i]) { if (context->child_bug) { - printf("WTF CLOSE IT\n"); switch_core_media_bug_close(&context->child_bug, SWITCH_TRUE); context->child_uuid = NULL; } @@ -575,6 +575,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi if (context->vfh.params) { const char *loopstr = switch_event_get_header(context->vfh.params, "loop"); + if (switch_true(loopstr)) { uint32_t pos = 0; switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET); @@ -612,7 +613,6 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi status = switch_core_file_read_video(&context->fg_vfh, &file_frame, SVR_FLUSH); switch_core_file_command(&context->fg_vfh, SCFC_FLUSH_AUDIO); - if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { int close = 1; @@ -840,41 +840,51 @@ static switch_status_t video_replace_thread_callback(switch_core_session_t *sess if (switch_test_flag(&context->vfh, SWITCH_FILE_OPEN)) { switch_status_t status = SWITCH_STATUS_FALSE; - if (type == SWITCH_ABC_TYPE_READ_VIDEO_PING || (context->vfh.params && switch_true(switch_event_get_header(context->vfh.params, "scale")))) { - context->vfh.mm.scale_w = frame->img->d_w; - context->vfh.mm.scale_h = frame->img->d_h; - } + //if (type == SWITCH_ABC_TYPE_READ_VIDEO_PING || (context->vfh.params && switch_true(switch_event_get_header(context->vfh.params, "scale")))) { + //context->vfh.mm.scale_w = frame->img->d_w; + //context->vfh.mm.scale_h = frame->img->d_h; + //} status = switch_core_file_read_video(&context->vfh, &file_frame, SVR_FLUSH); - switch_core_file_command(&context->vfh, SCFC_FLUSH_AUDIO); - + if (!context->sound) { + switch_core_file_command(&context->vfh, SCFC_FLUSH_AUDIO); + } + if (status != SWITCH_STATUS_SUCCESS && status != SWITCH_STATUS_BREAK) { int close = 1; - + if (context->vfh.params) { const char *loopstr = switch_event_get_header(context->vfh.params, "loop"); if (switch_true(loopstr)) { uint32_t pos = 0; - if (switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET) == SWITCH_STATUS_SUCCESS) close = 0; + switch_core_file_seek(&context->vfh, &pos, 0, SEEK_SET); + close = 0; } } if (close) { switch_core_file_close(&context->vfh); + switch_core_session_request_video_refresh(session); } } if (file_frame.img) { switch_img_free(&(context->rp_img)); - context->rp_img = file_frame.img; + + if (frame->img && (frame->img->d_w != file_frame.img->d_w || frame->img->d_h != file_frame.img->d_h)) { + switch_img_letterbox(file_frame.img, &context->rp_img, frame->img->d_w, frame->img->d_h, "#0000000"); + switch_img_free(&file_frame.img); + } else { + context->rp_img = file_frame.img; + } } if (context->rp_img) { if (context->rp_img->d_w != frame->img->d_w || context->rp_img->d_h != frame->img->d_h ) { frame->img = NULL; } - + switch_img_copy(context->rp_img, &frame->img); } } @@ -891,10 +901,17 @@ static switch_bool_t video_replace_bug_callback(switch_media_bug_t *bug, void *u switch (type) { case SWITCH_ABC_TYPE_INIT: { + switch_core_session_request_video_refresh(session); + switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); + switch_core_media_gen_key_frame(session); } break; case SWITCH_ABC_TYPE_CLOSE: { + switch_core_session_request_video_refresh(session); + switch_channel_set_flag(channel, CF_VIDEO_REFRESH_REQ); + switch_core_media_gen_key_frame(session); + switch_thread_rwlock_unlock(MODULE_INTERFACE->rwlock); switch_img_free(&context->rp_img); @@ -904,6 +921,33 @@ static switch_bool_t video_replace_bug_callback(switch_media_bug_t *bug, void *u } } break; + case SWITCH_ABC_TYPE_WRITE_REPLACE: + case SWITCH_ABC_TYPE_READ_REPLACE: + { + switch_frame_t *rframe = NULL; + switch_size_t len; + + if (type == SWITCH_ABC_TYPE_WRITE_REPLACE) { + rframe = switch_core_media_bug_get_write_replace_frame(bug); + } else { + rframe = switch_core_media_bug_get_read_replace_frame(bug); + } + + if (rframe) { + len = rframe->samples; + + if (switch_test_flag(&context->vfh, SWITCH_FILE_OPEN)) { + switch_core_file_read(&context->vfh, rframe->data, &len); + + if (len < rframe->samples) { + memset((char *)rframe->data + (len * 2 * context->vfh.channels), 0, (rframe->samples - len) * 2 * context->vfh.channels); + } + + rframe->datalen = rframe->samples * 2 * context->vfh.channels; + } + } + } + break; case SWITCH_ABC_TYPE_READ_VIDEO_PING: case SWITCH_ABC_TYPE_WRITE_VIDEO_PING: { @@ -936,7 +980,8 @@ SWITCH_STANDARD_APP(video_replace_start_function) char *argv[2] = { 0 }; char *direction = NULL; char *file = NULL; - + switch_codec_implementation_t read_impl = { 0 }; + if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_video_replace_bug_"))) { if (!zstr(data) && !strcasecmp(data, "stop")) { switch_channel_set_private(channel, "_video_replace_bug_", NULL); @@ -979,7 +1024,9 @@ SWITCH_STANDARD_APP(video_replace_start_function) switch_thread_rwlock_rdlock(MODULE_INTERFACE->rwlock); - if (switch_core_file_open(&context->vfh, file, 1, 8000, + switch_core_session_get_read_impl(session, &read_impl); + + if (switch_core_file_open(&context->vfh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO, switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening video file\n"); @@ -1014,7 +1061,9 @@ SWITCH_STANDARD_API(video_replace_api_function) char *direction = NULL; switch_media_bug_flag_t flags = 0; const char *function = "video_replace"; - + switch_codec_implementation_t read_impl = { 0 }; + int sound = 0; + if (zstr(cmd)) { goto usage; } @@ -1060,10 +1109,18 @@ SWITCH_STANDARD_API(video_replace_api_function) if (zstr(direction) || zstr(file)) goto usage; - if (!strcasecmp(direction, "read")) { + if (!strncasecmp(direction, "read", 4)) { flags = SMBF_READ_VIDEO_PING; - } else if (!strcasecmp(direction, "write")) { + if (switch_stristr(":sound", direction)) { + flags |= SMBF_READ_REPLACE; + sound = 1; + } + } else if (!strncasecmp(direction, "write", 5)) { flags = SMBF_WRITE_VIDEO_PING; + if (switch_stristr(":sound", direction)) { + flags |= SMBF_WRITE_REPLACE; + sound = 1; + } } else { goto usage; } @@ -1079,10 +1136,13 @@ SWITCH_STANDARD_API(video_replace_api_function) context = (video_replace_context_t *) switch_core_session_alloc(rsession, sizeof(*context)); switch_assert(context != NULL); context->session = rsession; - + context->sound = sound; switch_thread_rwlock_rdlock(MODULE_INTERFACE->rwlock); - if (switch_core_file_open(&context->vfh, file, 1, 8000, + + switch_core_session_get_read_impl(rsession, &read_impl); + + if (switch_core_file_open(&context->vfh, file, read_impl.number_of_channels, read_impl.actual_samples_per_second, SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT | SWITCH_FILE_FLAG_VIDEO, switch_core_session_get_pool(rsession)) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error opening video file\n"); diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 357ea3f07a..726073c7a3 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -1447,6 +1447,7 @@ static switch_bool_t record_callback(switch_media_bug_t *bug, void *user_data, s rh->fh->native_rate = rh->read_impl.actual_samples_per_second; if (switch_core_file_has_video(rh->fh, SWITCH_TRUE)) { switch_core_media_bug_set_media_params(bug, &rh->fh->mm); + switch_core_session_request_video_refresh(session); } } }