diff --git a/src/include/switch_types.h b/src/include/switch_types.h index a48d3a2aa9..949877d0bb 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1607,7 +1607,8 @@ typedef enum { SFF_SAME_IMAGE = (1 << 15), SFF_USE_VIDEO_TIMESTAMP = (1 << 16), SFF_ENCODED = (1 << 17), - SFF_TEXT_LINE_BREAK = (1 << 18) + SFF_TEXT_LINE_BREAK = (1 << 18), + SFF_IS_KEYFRAME = (1 << 19) } switch_frame_flag_enum_t; typedef uint32_t switch_frame_flag_t; 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 fdfc1088e0..52044bec1b 100644 --- a/src/mod/applications/mod_video_filter/mod_video_filter.c +++ b/src/mod/applications/mod_video_filter/mod_video_filter.c @@ -56,6 +56,8 @@ typedef struct chromakey_context_s { int mask_len; switch_core_session_t *session; switch_mutex_t *command_mutex; + int patch; + int mod; } chromakey_context_t; static void init_context(chromakey_context_t *context) @@ -85,11 +87,10 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char int n = argc - start; int i = start; - switch_core_session_request_video_refresh(context->session); - switch_core_media_gen_key_frame(context->session); - switch_mutex_lock(context->command_mutex); + context->patch = 0; + if (n > 0 && argv[i]) { // color int j = 0; char *list[MAX_MASK]; @@ -194,17 +195,18 @@ static void parse_params(chromakey_context_t *context, int start, int argc, char if (!strcasecmp(argv[i], "patch")) { *function = "patch:video"; *flags = SMBF_VIDEO_PATCH; + context->patch++; } i++; } - + switch_core_session_request_video_refresh(context->session); + context->mod++; switch_mutex_unlock(context->command_mutex); - switch_core_session_request_video_refresh(context->session); - switch_core_media_gen_key_frame(context->session); + } @@ -223,6 +225,13 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi return SWITCH_STATUS_SUCCESS; } + if (!context->patch && context->mod && !switch_test_flag(frame, SFF_IS_KEYFRAME)) { + switch_core_session_request_video_refresh(context->session); + return SWITCH_STATUS_SUCCESS; + } + + context->mod = 0; + if (switch_mutex_trylock(context->command_mutex) != SWITCH_STATUS_SUCCESS) { switch_img_patch(frame->img, context->last_img, 0, 0); return SWITCH_STATUS_SUCCESS; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 5a19e90462..9fa2585126 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2092,6 +2092,8 @@ static void check_jb(switch_core_session_t *session, const char *input, int32_t if (frames > 0) { switch_rtp_set_video_buffer_size(v_engine->rtp_session, frames, max_frames); + } else { + switch_rtp_deactivate_jitter_buffer(v_engine->rtp_session); } return; } else if (!strncasecmp(input, "vdebug:", 7)) { @@ -14036,6 +14038,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core uint32_t loops = 0; switch_media_handle_t *smh; int patchers = 0; + int is_keyframe = 0; switch_assert(session != NULL); @@ -14109,7 +14112,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core (*frame)->img = NULL; decode_status = switch_core_codec_decode_video((*frame)->codec, *frame); - + if (switch_test_flag(*frame, SFF_IS_KEYFRAME)) { + is_keyframe++; + } if ((*frame)->img && switch_channel_test_flag(session->channel, CF_VIDEO_DEBUG_READ)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "IMAGE %dx%d %dx%d\n", (*frame)->img->w, (*frame)->img->h, (*frame)->img->d_w, (*frame)->img->d_h); @@ -14152,6 +14157,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core done: + if (*frame && is_keyframe) { + switch_set_flag(*frame, SFF_IS_KEYFRAME); + } + if (session->bugs) { switch_media_bug_t *bp; int prune = 0; diff --git a/src/switch_vpx.c b/src/switch_vpx.c index ab2de6d501..78bf2245be 100644 --- a/src/switch_vpx.c +++ b/src/switch_vpx.c @@ -1178,6 +1178,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * } if (is_keyframe) { + switch_set_flag(frame, SFF_IS_KEYFRAME); if (context->got_key_frame <= 0) { context->got_key_frame = 1; context->no_key_frame = 0;