diff --git a/src/include/switch_channel.h b/src/include/switch_channel.h index 3c08d6a22d..d3267ae122 100644 --- a/src/include/switch_channel.h +++ b/src/include/switch_channel.h @@ -624,6 +624,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_timestamps(_In_ switch_channe SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel, const char *file, const char *func, int line); #define switch_channel_audio_sync(_c) switch_channel_perform_audio_sync(_c, __FILE__, __SWITCH_FUNC__, __LINE__) +SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line); +#define switch_channel_video_sync(_c) switch_channel_perform_video_sync(_c, __FILE__, __SWITCH_FUNC__, __LINE__) SWITCH_DECLARE(void) switch_channel_set_private_flag(switch_channel_t *channel, uint32_t flags); SWITCH_DECLARE(void) switch_channel_clear_private_flag(switch_channel_t *channel, uint32_t flags); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 917638bede..cec2f605bc 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -1046,6 +1046,7 @@ typedef enum { SWITCH_MESSAGE_INDICATE_DISPLAY, SWITCH_MESSAGE_INDICATE_TRANSCODING_NECESSARY, SWITCH_MESSAGE_INDICATE_AUDIO_SYNC, + SWITCH_MESSAGE_INDICATE_VIDEO_SYNC, SWITCH_MESSAGE_INDICATE_REQUEST_IMAGE_MEDIA, SWITCH_MESSAGE_INDICATE_UUID_CHANGE, SWITCH_MESSAGE_INDICATE_SIMPLIFY, diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 53cf751114..cae64d20a7 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -3935,6 +3935,7 @@ SWITCH_STANDARD_API(uuid_video_refresh_function) if ((lsession = switch_core_session_locate(argv[0]))) { switch_core_session_video_reinit(lsession); + switch_channel_video_sync(switch_core_session_get_channel(lsession)); status = SWITCH_STATUS_SUCCESS; switch_core_session_rwunlock(lsession); } diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index b262b794f5..dcb6580b54 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -1806,6 +1806,8 @@ static int flush_video_queue(switch_queue_t *q) void *pop; int r = 0; + if (!q) return 0; + while (switch_queue_trypop(q, &pop) == SWITCH_STATUS_SUCCESS && pop) { img = (switch_image_t *)pop; switch_img_free(&img); @@ -2000,8 +2002,13 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread } size = switch_queue_size(imember->video_queue); } while(size > 0); - if (!img) { + if (!img && switch_test_flag(imember, MFLAG_CAN_BE_SEEN)) { imember->blanks++; + + if (imember->blanks == conference->video_fps.fps || (imember->blanks % (int)(conference->video_fps.fps * 10)) == 0) { + switch_core_session_request_video_refresh(imember->session); + } + if (imember->blanks == conference->video_fps.fps * 2) { check_avatar(imember, SWITCH_TRUE); if (layer && imember->avatar_png_img) { @@ -2015,6 +2022,8 @@ static void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread if (flushed && imember->blanks) { switch_img_free(&imember->avatar_png_img); imember->blanks = 0; + switch_core_session_request_video_refresh(imember->session); + switch_channel_video_sync(imember->channel); } img = imember->avatar_png_img; @@ -4775,7 +4784,7 @@ static switch_status_t video_thread_callback(switch_core_session_t *session, swi if (switch_test_flag(member->conference, CFLAG_VIDEO_MUXING)) { switch_image_t *img_copy = NULL; - if (frame->img && !member->conference->playing_video_file) { + if (frame->img && !member->conference->playing_video_file && switch_queue_size(member->video_queue) < 3) { switch_img_copy(frame->img, &img_copy); switch_queue_push(member->video_queue, img_copy); } @@ -8302,6 +8311,8 @@ static switch_status_t conf_api_sub_vmute(conference_member_t *member, switch_st if (member->channel) { switch_channel_set_flag(member->channel, CF_VIDEO_PAUSE_READ); + switch_core_session_request_video_refresh(member->session); + switch_channel_video_sync(member->channel); } if (!(data) || !strstr((char *) data, "quiet")) { @@ -8358,6 +8369,8 @@ static switch_status_t conf_api_sub_unvmute(conference_member_t *member, switch_ if (member->channel) { switch_channel_clear_flag(member->channel, CF_VIDEO_PAUSE_READ); + switch_core_session_request_video_refresh(member->session); + switch_channel_video_sync(member->channel); } if (!(data) || !strstr((char *) data, "quiet")) { diff --git a/src/mod/codecs/mod_vpx/mod_vpx.c b/src/mod/codecs/mod_vpx/mod_vpx.c index f3eb3034d3..1d25acd45e 100644 --- a/src/mod/codecs/mod_vpx/mod_vpx.c +++ b/src/mod/codecs/mod_vpx/mod_vpx.c @@ -772,7 +772,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * if (context->is_vp9) { is_keyframe = IS_VP9_KEY_FRAME(*(unsigned char *)frame->data); } else { // vp8 - is_keyframe = IS_VP8_KEY_FRAME((uint8_t *)frame->data); + is_keyframe = (*(unsigned char *)frame->data & 0x10) || IS_VP8_KEY_FRAME((uint8_t *)frame->data); } // if (is_keyframe) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "got key %d\n", is_keyframe); @@ -843,7 +843,7 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * err = vpx_codec_decode(decoder, data, (unsigned int)len, NULL, 0); if (err != VPX_CODEC_OK) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n", + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Error decoding %" SWITCH_SIZE_T_FMT " bytes, [%d:%s:%s]\n", len, err, vpx_codec_error(decoder), vpx_codec_error_detail(decoder)); switch_goto_status(SWITCH_STATUS_RESTART, end); } @@ -869,9 +869,9 @@ static switch_status_t switch_vpx_decode(switch_codec_t *codec, switch_frame_t * end: - if (status == SWITCH_STATUS_RESTART) { - context->need_decoder_reset = 1; - } + //if (status == SWITCH_STATUS_RESTART) { + // context->need_decoder_reset = 1; + //} if (!frame->img || status == SWITCH_STATUS_RESTART) { status = SWITCH_STATUS_MORE_DATA; diff --git a/src/switch_channel.c b/src/switch_channel.c index 0c271468dd..60b3b62b35 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -361,6 +361,20 @@ SWITCH_DECLARE(void) switch_channel_perform_audio_sync(switch_channel_t *channel } +SWITCH_DECLARE(void) switch_channel_perform_video_sync(switch_channel_t *channel, const char *file, const char *func, int line) +{ + if (switch_channel_media_up(channel)) { + switch_core_session_message_t msg = { 0 }; + msg.message_id = SWITCH_MESSAGE_INDICATE_VIDEO_SYNC; + msg.from = channel->name; + msg._file = file; + msg._func = func; + msg._line = line; + switch_core_session_receive_message(channel->session, &msg); + } +} + + SWITCH_DECLARE(switch_call_cause_t) switch_channel_cause_q850(switch_call_cause_t cause) { diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 1cb54a1c06..87ad918108 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -8748,6 +8748,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } goto end; + case SWITCH_MESSAGE_INDICATE_VIDEO_SYNC: + if (switch_rtp_ready(v_engine->rtp_session)) { + switch_rtp_flush(v_engine->rtp_session); + } + goto end; + case SWITCH_MESSAGE_INDICATE_MEDIA: { diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 2aadb0323f..6ddeee6c75 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -4069,9 +4069,7 @@ SWITCH_DECLARE(void) switch_rtp_flush(switch_rtp_t *rtp_session) return; } - if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); - } + switch_rtp_set_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); } SWITCH_DECLARE(void) switch_rtp_video_refresh(switch_rtp_t *rtp_session) @@ -4396,10 +4394,6 @@ SWITCH_DECLARE(void) switch_rtp_clear_flags(switch_rtp_t *rtp_session, switch_rt SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_flag_t flag) { - if (flag == SWITCH_RTP_FLAG_FLUSH && rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - return; - } - switch_mutex_lock(rtp_session->flag_mutex); rtp_session->flags[flag] = 1; switch_mutex_unlock(rtp_session->flag_mutex); @@ -4423,7 +4417,11 @@ SWITCH_DECLARE(void) switch_rtp_set_flag(switch_rtp_t *rtp_session, switch_rtp_f } } } + + rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE); + + if (rtp_session->jb) { stfu_n_reset(rtp_session->jb); } @@ -4635,7 +4633,6 @@ SWITCH_DECLARE(void) rtp_flush_read_buffer(switch_rtp_t *rtp_session, switch_rtp { if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || - rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) { return; } @@ -4684,11 +4681,11 @@ static void do_flush(switch_rtp_t *rtp_session, int force) if (!switch_rtp_ready(rtp_session)) { return; } + reset_jitter_seq(rtp_session); if (!force) { if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || - rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL] || rtp_session->flags[SWITCH_RTP_FLAG_DTMF_ON] ) { @@ -4701,14 +4698,22 @@ static void do_flush(switch_rtp_t *rtp_session, int force) if (switch_rtp_ready(rtp_session) ) { if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { - goto end; + stfu_n_reset(rtp_session->jb); + } + + if (rtp_session->vb) { + switch_vb_reset(rtp_session->vb); + } + + if (rtp_session->vbw) { + switch_vb_reset(rtp_session->vbw); } if (rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), - SWITCH_LOG_CONSOLE, "%s FLUSH\n", - rtp_session->session ? switch_channel_get_name(switch_core_session_get_channel(rtp_session->session)) : "NoName" - ); + SWITCH_LOG_CONSOLE, "%s FLUSH\n", + rtp_session->session ? switch_channel_get_name(switch_core_session_get_channel(rtp_session->session)) : "NoName" + ); } if (!rtp_session->flags[SWITCH_RTP_FLAG_NOBLOCK]) { @@ -4757,8 +4762,6 @@ static void do_flush(switch_rtp_t *rtp_session, int force) } } - end: - READ_DEC(rtp_session); } @@ -6076,10 +6079,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ check = !bytes; if (rtp_session->flags[SWITCH_RTP_FLAG_FLUSH]) { - if (!rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) { - do_flush(rtp_session, SWITCH_FALSE); - bytes = 0; - } + do_flush(rtp_session, SWITCH_FALSE); + bytes = 0; switch_rtp_clear_flag(rtp_session, SWITCH_RTP_FLAG_FLUSH); } @@ -6104,7 +6105,8 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } if (bytes && rtp_session->recv_msg.header.m && rtp_session->recv_msg.header.pt != rtp_session->recv_te && - !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { + !rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] && + !(rtp_session->rtp_bugs & RTP_BUG_IGNORE_MARK_BIT)) { rtp_flush_read_buffer(rtp_session, SWITCH_RTP_FLUSH_ONCE); }