diff --git a/src/include/switch_core.h b/src/include/switch_core.h index c0af4c00dc..52b643e5eb 100644 --- a/src/include/switch_core.h +++ b/src/include/switch_core.h @@ -1274,6 +1274,9 @@ SWITCH_DECLARE(uint32_t) switch_core_session_private_event_count(_In_ switch_cor SWITCH_DECLARE(switch_status_t) switch_core_session_dequeue_private_event(_In_ switch_core_session_t *session, _Out_ switch_event_t **event); +SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type); +SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on); + /*! \brief Flush the private event queue of a session \param session the session to flush diff --git a/src/include/switch_module_interfaces.h b/src/include/switch_module_interfaces.h index 1802f872e3..e0a5c2019e 100644 --- a/src/include/switch_module_interfaces.h +++ b/src/include/switch_module_interfaces.h @@ -207,6 +207,7 @@ struct switch_timer { unsigned int samples; /*! current sample count based on samples parameter */ uint32_t samplecount; + uint32_t last_samplecount; /*! the timer interface provided from a loadable module */ switch_timer_interface_t *timer_interface; /*! the timer's memory pool */ diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 03e141d536..47ea86b252 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -770,8 +770,6 @@ typedef enum { SWITCH_RTP_FLAG_MUTE, SWITCH_RTP_FLAG_NACK, SWITCH_RTP_FLAG_TMMBR, - SWITCH_RTP_FLAG_GEN_TS_DELTA, - SWITCH_RTP_FLAG_GEN_TS_MANUAL, SWITCH_RTP_FLAG_DETECT_SSRC, SWITCH_RTP_FLAG_OLD_FIR, SWITCH_RTP_FLAG_PASSTHRU, @@ -905,7 +903,6 @@ typedef enum { */ - } switch_rtp_bug_flag_t; #ifdef _MSC_VER @@ -1530,6 +1527,8 @@ typedef struct switch_vid_params_s { uint32_t width; uint32_t height; uint32_t fps; + uint32_t d_width; + uint32_t d_height; } switch_vid_params_t; diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index e9bee8b523..acedda36d4 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -41,42 +41,25 @@ */ #include -static struct conference_fps FPS_VALS[] = { - {1.0f, 1000, 90}, - {5.0f, 200, 450}, - {10.0f, 100, 900}, - {15.0f, 66, 1364}, - {16.60f, 60, 1500}, - {20.0f, 50, 4500}, - {25.0f, 40, 2250}, - {30.0f, 33, 2700}, - {33.0f, 30, 2790}, - {66.60f, 15, 6000}, - {100.0f, 10, 9000}, - {0,0,0} -}; - - int conference_video_set_fps(conference_obj_t *conference, float fps) { - uint32_t i = 0, j = 0; + uint32_t j = 0; - for (i = 0; FPS_VALS[i].ms; i++) { - if (FPS_VALS[i].fps == fps) { + if (fps > 100) { + return 0; + } - conference->video_fps = FPS_VALS[i]; + conference->video_fps.fps = fps; + conference->video_fps.ms = (int) 1000 / fps; + conference->video_fps.samples = (int) 90000 / conference->video_fps.ms; - for (j = 0; j <= conference->canvas_count; j++) { - if (conference->canvases[j]) { - conference->canvases[j]->video_timer_reset = 1; - } - } - - return 1; + for (j = 0; j <= conference->canvas_count; j++) { + if (conference->canvases[j]) { + conference->canvases[j]->video_timer_reset = 1; } } - return 0; + return 1; } @@ -1312,7 +1295,7 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer } if (frame->timestamp) { - switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME); + switch_set_flag(frame, SFF_RAW_RTP_PARSE_FRAME|SFF_USE_VIDEO_TIMESTAMP); } frame->packetlen = frame->datalen + 12; @@ -1342,7 +1325,9 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || + switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } @@ -2996,6 +2981,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (!imember->rec && (!imember->session || !switch_channel_test_flag(imember->channel, CF_VIDEO_READY) || !imember->canvas || + switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || switch_core_session_read_lock(imember->session) != SWITCH_STATUS_SUCCESS)) { continue; } @@ -3196,7 +3182,9 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || + switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } @@ -3206,13 +3194,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_media_gen_key_frame(imember->session); } - switch_set_flag(&write_frame, SFF_RAW_RTP); + switch_set_flag(&write_frame, SFF_RAW_RTP|SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP_PARSE_FRAME); write_frame.img = write_img; write_frame.packet = packet; write_frame.data = ((uint8_t *)packet) + 12; write_frame.datalen = 0; write_frame.buflen = SWITCH_RTP_MAX_BUF_LEN - 12; write_frame.packetlen = 0; + write_frame.timestamp = timestamp; //switch_core_session_write_video_frame(imember->session, &write_frame, SWITCH_IO_FLAG_NONE, 0); @@ -3545,7 +3534,9 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ switch_core_session_request_video_refresh(imember->session); } - if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { + if (switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || + switch_channel_test_flag(imember->channel, CF_VIDEO_WRITING) || + switch_core_session_media_flow(imember->session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_core_session_rwunlock(imember->session); continue; } diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 727005b00b..397b71e2de 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -53,7 +53,8 @@ static void gen_ice(switch_core_session_t *session, switch_media_type_t type, co typedef enum { SMF_INIT = (1 << 0), SMF_READY = (1 << 1), - SMF_JB_PAUSED = (1 << 2) + SMF_JB_PAUSED = (1 << 2), + SMF_VB_PAUSED = (1 << 3) } smh_flag_t; @@ -173,6 +174,7 @@ typedef struct switch_rtp_engine_s { switch_media_flow_t rmode; switch_media_flow_t smode; switch_thread_id_t thread_id; + switch_thread_id_t thread_write_lock; uint8_t new_ice; uint8_t new_dtls; uint32_t sdp_bw; @@ -2651,6 +2653,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_write_frame(switch_core_sessio engine = &smh->engines[type]; + if (type == SWITCH_MEDIA_TYPE_VIDEO) { + if (engine->thread_write_lock && engine->thread_write_lock != switch_thread_self()) { + return SWITCH_STATUS_SUCCESS; + } + } if (switch_channel_test_flag(session->channel, CF_VIDEO_ONLY) && type == SWITCH_MEDIA_TYPE_AUDIO) { return SWITCH_STATUS_SUCCESS; @@ -5390,7 +5397,7 @@ SWITCH_DECLARE(switch_file_handle_t *) switch_core_media_get_video_file(switch_c return fh; } -static void switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms) +SWITCH_DECLARE(void) switch_core_session_write_blank_video(switch_core_session_t *session, uint32_t ms) { switch_frame_t fr = { 0 }; int i = 0; @@ -5446,6 +5453,20 @@ static void switch_core_session_write_blank_video(switch_core_session_t *session } +typedef struct core_fps_s { + float fps; + int ms; + int samples; +} core_fps_t; + +static int video_get_fps(core_fps_t *fpsP, float fps) +{ + fpsP->fps = fps; + fpsP->ms = (int) 1000 / fps; + fpsP->samples = (int) 90000 / fpsP->ms; + + return 0; +} static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void *obj) { @@ -5457,9 +5478,11 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void int buflen = SWITCH_RTP_MAX_BUF_LEN; switch_timer_t timer = { 0 }; int fps; - switch_video_read_flag_t read_flags = SVR_FLUSH|SVR_BLOCK; + switch_video_read_flag_t read_flags = SVR_FLUSH; switch_core_session_t *b_session = NULL; - + core_fps_t fps_data = { 0 }; + switch_image_t *last_frame = NULL; + if (switch_core_session_read_lock(session) != SWITCH_STATUS_SUCCESS) { return NULL; } @@ -5478,7 +5501,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + switch_mutex_lock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]); + v_engine->thread_write_lock = switch_thread_self(); + buf = switch_core_session_alloc(session, buflen); fr.packet = buf; fr.packetlen = buflen; @@ -5498,7 +5524,8 @@ 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)); + video_get_fps(&fps_data, fps); + switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, switch_core_session_get_pool(session)); 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)) { @@ -5509,15 +5536,27 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void if (smh->video_write_fh && 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)); + video_get_fps(&fps_data, fps); + switch_core_timer_init(&timer, "soft", (int)(1000 / fps) , fps_data.samples, 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, read_flags); if (wstatus == SWITCH_STATUS_SUCCESS) { - switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, SVR_FLUSH); - switch_img_free(&fr.img); + fr.timestamp = timer.samplecount; + fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME; + + if (smh->vid_params.d_width && smh->vid_params.d_height) { + switch_img_fit(&fr.img, smh->vid_params.d_width, smh->vid_params.d_height, SWITCH_FIT_SIZE); + } + + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0); + + switch_img_free(&last_frame); + last_frame = fr.img; + fr.img = NULL; + } else if (wstatus != SWITCH_STATUS_BREAK && wstatus != SWITCH_STATUS_IGNORE) { switch_set_flag_locked(smh->video_write_fh, SWITCH_FILE_FLAG_VIDEO_EOF); } @@ -5525,6 +5564,25 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_mutex_unlock(v_engine->mh.file_write_mutex); } + if (last_frame) { + int x = 0; + switch_rgb_color_t bgcolor; + switch_color_set_rgb(&bgcolor, "#000000"); + switch_img_fill(last_frame, 0, 0, last_frame->d_w, last_frame->d_h, &bgcolor); + fr.img = last_frame; + + for (x = 0; x < fps / 2; x++) { + switch_core_timer_next(&timer); + fr.timestamp = timer.samplecount; + fr.flags = SFF_USE_VIDEO_TIMESTAMP|SFF_RAW_RTP|SFF_RAW_RTP_PARSE_FRAME; + switch_core_session_write_video_frame(session, &fr, SWITCH_IO_FLAG_FORCE, 0); + } + switch_core_media_gen_key_frame(session); + switch_core_session_request_video_refresh(session); + switch_img_free(&last_frame); + } + + switch_core_timer_destroy(&timer); switch_core_session_rwunlock(session); @@ -5534,6 +5592,10 @@ static void *SWITCH_THREAD_FUNC video_write_thread(switch_thread_t *thread, void switch_core_session_rwunlock(b_session); } + + v_engine->thread_write_lock = 0; + switch_mutex_unlock(smh->write_mutex[SWITCH_MEDIA_TYPE_VIDEO]); + switch_channel_clear_flag(session->channel, CF_VIDEO_WRITING); smh->video_write_thread_running = 0; @@ -5675,7 +5737,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses if (fh) { switch_threadattr_t *thd_attr = NULL; - switch_core_session_write_blank_video(session, 500); + //switch_core_session_write_blank_video(session, 500); switch_threadattr_create(&thd_attr, switch_core_session_get_pool(session)); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); smh->video_write_thread_running = 1; @@ -5692,7 +5754,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_set_video_file(switch_core_ses switch_thread_join(&st, smh->video_write_thread); switch_mutex_lock(v_engine->mh.file_write_mutex); smh->video_write_thread = NULL; - switch_core_session_write_blank_video(session, 500); + //switch_core_session_write_blank_video(session, 500); } smh->video_write_fh = fh; @@ -6887,11 +6949,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi } - if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_audio")) && switch_true(val)) { - flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1; - flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1; - } - if (switch_channel_up(session->channel)) { switch_channel_set_variable(session->channel, "rtp_use_timer_name", timer_name); @@ -7292,11 +7349,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi flags[SWITCH_RTP_FLAG_AUTOADJ]++; } - if ((val = switch_channel_get_variable(session->channel, "rtp_gen_ts_delta_video")) && switch_true(val)) { - flags[SWITCH_RTP_FLAG_GEN_TS_MANUAL] = 1; - flags[SWITCH_RTP_FLAG_GEN_TS_DELTA] = 1; - } - if (switch_channel_test_flag(session->channel, CF_PROXY_MEDIA)) { flags[SWITCH_RTP_FLAG_PROXY_MEDIA]++; } @@ -10034,8 +10086,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se const char *val; int ok = 0; - if (!switch_channel_test_flag(session->channel, CF_VIDEO) && - (!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) { + if ((!(val = switch_channel_get_variable(session->channel, "rtp_jitter_buffer_during_bridge")) || switch_false(val))) { if (switch_channel_test_flag(session->channel, CF_JITTERBUFFER) && switch_channel_test_cap_partner(session->channel, CC_FS_RTP)) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "%s PAUSE Jitterbuffer\n", switch_channel_get_name(session->channel)); @@ -10089,6 +10140,20 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_receive_message(switch_core_se } goto end; case SWITCH_MESSAGE_INDICATE_UNBRIDGE: + +#if 0 + if (switch_rtp_ready(v_engine->rtp_session)) { + + if (switch_test_flag(smh, SMF_VB_PAUSED)) { + switch_clear_flag(smh, SMF_VB_PAUSED); + switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, + "%s RESUME Video Jitterbuffer\n", switch_channel_get_name(session->channel)); + switch_rtp_pause_jitter_buffer(v_engine->rtp_session, SWITCH_FALSE); + + } + } +#endif + if (switch_rtp_ready(a_engine->rtp_session)) { if (switch_test_flag(smh, SMF_JB_PAUSED)) { @@ -11694,8 +11759,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor switch_image_t *dup_img = NULL, *img = frame->img; switch_status_t encode_status; switch_frame_t write_frame = {0}; - switch_rtp_engine_t *v_engine; - + switch_rtp_engine_t *v_engine = NULL; switch_assert(session); if (!(smh = session->media_handle)) { @@ -11711,9 +11775,6 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor return SWITCH_STATUS_FALSE; } - if (switch_channel_test_flag(session->channel, CF_VIDEO_WRITING) && !(flags & SWITCH_IO_FLAG_FORCE)) { - return SWITCH_STATUS_SUCCESS; - } if (switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_RECVONLY || switch_core_session_media_flow(session, SWITCH_MEDIA_TYPE_VIDEO) == SWITCH_MEDIA_FLOW_INACTIVE) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG3, "Writing video to RECVONLY/INACTIVE session\n"); @@ -11736,6 +11797,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor return SWITCH_STATUS_INUSE; } + v_engine = &smh->engines[SWITCH_MEDIA_TYPE_VIDEO]; + if (v_engine->thread_write_lock && v_engine->thread_write_lock != switch_thread_self()) { + return SWITCH_STATUS_SUCCESS; + } + if (!smh->video_init && smh->mparams->video_key_first && (now - smh->video_last_key_time) > smh->mparams->video_key_first) { switch_core_media_gen_key_frame(session); @@ -11753,17 +11819,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor if (!img) { switch_status_t vstatus; - - if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) { - switch_rtp_set_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA); - } vstatus = switch_core_session_write_encoded_video_frame(session, frame, flags, stream_id); switch_goto_status(vstatus, done); - } else { - if (!switch_rtp_test_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_MANUAL)) { - switch_rtp_clear_flag(v_engine->rtp_session, SWITCH_RTP_FLAG_GEN_TS_DELTA); - } } @@ -11776,6 +11834,11 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_write_video_frame(switch_cor img = dup_img; } + + if (!switch_channel_test_flag(session->channel, CF_VIDEO_WRITING)) { + smh->vid_params.d_width = img->d_w; + smh->vid_params.d_height = img->d_h; + } if (session->bugs) { switch_media_bug_t *bp; @@ -11949,6 +12012,53 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_wait_for_video_input_params( } +SWITCH_DECLARE(switch_bool_t) switch_core_session_transcoding(switch_core_session_t *session_a, switch_core_session_t *session_b, switch_media_type_t type) +{ + switch_bool_t transcoding = SWITCH_FALSE; + + switch(type) { + case SWITCH_MEDIA_TYPE_AUDIO: + transcoding = (session_a->read_codec->implementation->impl_id != session_b->read_codec->implementation->impl_id || session_a->read_impl.decoded_bytes_per_packet != session_b->read_impl.decoded_bytes_per_packet); + break; + case SWITCH_MEDIA_TYPE_VIDEO: + transcoding = (switch_channel_test_flag(session_a->channel, CF_VIDEO_DECODED_READ) || + switch_channel_test_flag(session_b->channel, CF_VIDEO_DECODED_READ)); + break; + default: + break; + } + + return transcoding; + +} + +SWITCH_DECLARE(void) switch_core_session_passthru(switch_core_session_t *session, switch_media_type_t type, switch_bool_t on) +{ + switch_rtp_engine_t *engine; + + if (!session->media_handle) return; + + engine = &session->media_handle->engines[type]; + + + if (switch_rtp_ready(engine->rtp_session)) { + if (on) { + switch_rtp_set_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU); + } else { + switch_rtp_clear_flag(engine->rtp_session, SWITCH_RTP_FLAG_PASSTHRU); + } + + if (type == SWITCH_MEDIA_TYPE_VIDEO) { + switch_core_session_request_video_refresh(session); + if (!on) { + switch_core_media_gen_key_frame(session); + } + } + + } + +} + SWITCH_DECLARE(switch_status_t) switch_core_session_read_video_frame(switch_core_session_t *session, switch_frame_t **frame, switch_io_flag_t flags, int stream_id) { diff --git a/src/switch_ivr_bridge.c b/src/switch_ivr_bridge.c index 654aa492ac..8c0c1e7bec 100644 --- a/src/switch_ivr_bridge.c +++ b/src/switch_ivr_bridge.c @@ -55,6 +55,7 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) switch_frame_t *read_frame = 0; int set_decoded_read = 0, refresh_timer = 0; int refresh_cnt = 300; + int pass_val = 0, last_pass_val = 0; vh->up = 1; @@ -78,8 +79,18 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) if (switch_channel_media_up(channel)) { switch_codec_t *a_codec = switch_core_session_get_video_read_codec(vh->session_a); switch_codec_t *b_codec = switch_core_session_get_video_write_codec(vh->session_b); + + if (switch_core_session_transcoding(vh->session_a, vh->session_b, SWITCH_MEDIA_TYPE_VIDEO)) { + pass_val = 1; + } else { + pass_val = 2; + } - + if (pass_val != last_pass_val) { + switch_core_session_passthru(session, SWITCH_MEDIA_TYPE_VIDEO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE); + last_pass_val = pass_val; + } + if (switch_channel_test_flag(channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(channel, CF_VIDEO_REFRESH_REQ); refresh_timer = refresh_cnt; @@ -146,6 +157,8 @@ static void video_bridge_thread(switch_core_session_t *session, void *obj) switch_core_session_request_video_refresh(vh->session_a); switch_core_session_request_video_refresh(vh->session_b); + switch_core_session_passthru(vh->session_a, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_FALSE); + switch_core_session_rwunlock(vh->session_a); switch_core_session_rwunlock(vh->session_b); @@ -268,6 +281,7 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_codec_implementation_t read_impl = { 0 }; const char *banner_file = NULL; int played_banner = 0, banner_counter = 0; + int pass_val = 0, last_pass_val = 0; #ifdef SWITCH_VIDEO_IN_THREADS struct vid_helper vh = { 0 }; @@ -398,6 +412,17 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) switch_status_t status; switch_event_t *event; + if (switch_core_session_transcoding(session_a, session_b, SWITCH_MEDIA_TYPE_AUDIO)) { + pass_val = 1; + } else { + pass_val = 2; + } + + if (pass_val != last_pass_val) { + switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, pass_val == 2 ? SWITCH_TRUE : SWITCH_FALSE); + last_pass_val = pass_val; + } + if (switch_channel_test_flag(chan_a, CF_TRANSFER)) { data->clean_exit = 1; } @@ -702,6 +727,8 @@ static void *audio_bridge_thread(switch_thread_t *thread, void *obj) } #endif + switch_core_session_passthru(session_a, SWITCH_MEDIA_TYPE_AUDIO, SWITCH_FALSE); + if (silence_val) { switch_core_codec_destroy(&silence_codec); diff --git a/src/switch_time.c b/src/switch_time.c index 8554c5c9f3..b450f13b31 100644 --- a/src/switch_time.c +++ b/src/switch_time.c @@ -386,6 +386,14 @@ static switch_status_t timer_generic_sync(switch_timer_t *timer) timer->tick = (elapsed / timer->interval) / 1000; timer->samplecount = (uint32_t)(timer->tick * timer->samples); + if (timer->interval == 1 && timer->samplecount == timer->last_samplecount) { + timer->samplecount++; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "Timer sync too often\n"); + } + timer->last_samplecount = timer->samplecount; + + + return SWITCH_STATUS_SUCCESS; }