diff --git a/src/include/switch_core_media.h b/src/include/switch_core_media.h index 906dbacb72..5c7c993238 100644 --- a/src/include/switch_core_media.h +++ b/src/include/switch_core_media.h @@ -314,7 +314,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess #define switch_core_media_gen_key_frame(_session) switch_core_media_codec_control(_session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_WRITE, \ - SCC_VIDEO_REFRESH, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL) \ + SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL) \ #define switch_core_media_write_bandwidth(_session, _val) switch_core_media_codec_control(_session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_WRITE, \ SCC_VIDEO_BANDWIDTH, SCCT_STRING, _val, SCCT_NONE, NULL, NULL, NULL) \ diff --git a/src/include/switch_jitterbuffer.h b/src/include/switch_jitterbuffer.h index 08a71fae0a..de423fd7fd 100644 --- a/src/include/switch_jitterbuffer.h +++ b/src/include/switch_jitterbuffer.h @@ -54,7 +54,6 @@ SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb); SWITCH_DECLARE(void) switch_jb_debug_level(switch_jb_t *jb, uint8_t level); SWITCH_DECLARE(int) switch_jb_frame_count(switch_jb_t *jb); SWITCH_DECLARE(int) switch_jb_poll(switch_jb_t *jb); -SWITCH_DECLARE(switch_status_t) switch_jb_push_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len); SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len); SWITCH_DECLARE(switch_size_t) switch_jb_get_last_read_len(switch_jb_t *jb); SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t *len); diff --git a/src/include/switch_types.h b/src/include/switch_types.h index 98bdf94d48..126f722ce2 100644 --- a/src/include/switch_types.h +++ b/src/include/switch_types.h @@ -2244,7 +2244,7 @@ typedef switch_status_t (*switch_core_codec_video_encode_func_t) (switch_codec_t typedef switch_status_t (*switch_core_codec_video_decode_func_t) (switch_codec_t *codec, switch_frame_t *frame); typedef enum { - SCC_VIDEO_REFRESH = 0, + SCC_VIDEO_GEN_KEYFRAME = 0, SCC_VIDEO_BANDWIDTH, SCC_VIDEO_RESET, SCC_AUDIO_PACKET_LOSS, diff --git a/src/mod/applications/mod_av/avcodec.c b/src/mod/applications/mod_av/avcodec.c index 89a2781dee..5d4a0e1a16 100644 --- a/src/mod/applications/mod_av/avcodec.c +++ b/src/mod/applications/mod_av/avcodec.c @@ -1294,7 +1294,7 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info; switch(cmd) { - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 07dc306d2c..4e42afc3af 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1200,7 +1200,7 @@ void conference_video_destroy_canvas(mcu_canvas_t **canvasP) { void conference_video_write_canvas_image_to_codec_group(conference_obj_t *conference, mcu_canvas_t *canvas, codec_set_t *codec_set, int codec_index, uint32_t timestamp, switch_bool_t need_refresh, - switch_bool_t need_keyframe, switch_bool_t need_reset) + switch_bool_t send_keyframe, switch_bool_t need_reset) { conference_member_t *imember; @@ -1223,8 +1223,8 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer need_refresh = SWITCH_TRUE; } - if (need_refresh || need_keyframe) { - switch_core_codec_control(&codec_set->codec, SCC_VIDEO_REFRESH, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL); + if (send_keyframe) { + switch_core_codec_control(&codec_set->codec, SCC_VIDEO_GEN_KEYFRAME, SCCT_NONE, NULL, SCCT_NONE, NULL, NULL, NULL); } do { @@ -1270,9 +1270,9 @@ void conference_video_write_canvas_image_to_codec_group(conference_obj_t *confer continue; } - //if (need_refresh) { - // switch_core_session_request_video_refresh(imember->session); - //} + if (need_refresh) { + switch_core_session_request_video_refresh(imember->session); + } //switch_core_session_write_encoded_video_frame(imember->session, frame, 0, 0); switch_set_flag(frame, SFF_ENCODED); @@ -1429,6 +1429,7 @@ void conference_video_launch_muxing_write_thread(conference_member_t *member) switch_mutex_lock(conference_globals.hash_mutex); if (!member->video_muxing_write_thread) { switch_threadattr_create(&thd_attr, member->pool); + switch_threadattr_priority_set(thd_attr, SWITCH_PRI_REALTIME); switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE); switch_thread_create(&member->video_muxing_write_thread, thd_attr, conference_video_muxing_write_thread_run, member, member->pool); } @@ -1456,61 +1457,75 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_write_thread_run(switch_thread_ void *pop; switch_frame_t *frame; int loops = 0; - + switch_time_t last = 0; + if (switch_thread_rwlock_tryrdlock(member->rwlock) != SWITCH_STATUS_SUCCESS) { return NULL; } while(conference_utils_member_test_flag(member, MFLAG_RUNNING)) { - if (conference_utils_member_test_flag(member, MFLAG_RUNNING)) { - if (switch_queue_pop(member->mux_out_queue, &pop) == SWITCH_STATUS_SUCCESS) { - mcu_layer_t *layer = NULL; - mcu_canvas_t *canvas = NULL; + if (switch_queue_pop(member->mux_out_queue, &pop) == SWITCH_STATUS_SUCCESS) { + mcu_layer_t *layer = NULL; + mcu_canvas_t *canvas = NULL; - if (!pop) { - break; - } + if (!pop) { + break; + } - if (loops == 0 || loops == 50) { - switch_core_media_gen_key_frame(member->session); - switch_core_session_request_video_refresh(member->session); + if (loops == 0 || loops == 50) { + switch_core_media_gen_key_frame(member->session); + switch_core_session_request_video_refresh(member->session); + } + + loops++; + + if ((switch_size_t)pop != 1) { + frame = (switch_frame_t *) pop; + if (switch_test_flag(frame, SFF_ENCODED)) { + switch_core_session_write_encoded_video_frame(member->session, frame, 0, 0); + } else { + switch_core_session_write_video_frame(member->session, frame, SWITCH_IO_FLAG_NONE, 0); } - loops++; - - if ((switch_size_t)pop != 1) { - frame = (switch_frame_t *) pop; - if (switch_test_flag(frame, SFF_ENCODED)) { - switch_core_session_write_encoded_video_frame(member->session, frame, 0, 0); - } else { - switch_core_session_write_video_frame(member->session, frame, SWITCH_IO_FLAG_NONE, 0); + if (!switch_test_flag(frame, SFF_ENCODED) || frame->m) { + switch_time_t now = switch_time_now(); + + if (last) { + int delta = now - last; + if (delta > member->conference->video_fps.ms * 2) { + switch_core_session_request_video_refresh(member->session); + } } - switch_frame_buffer_free(member->fb, &frame); + last = now; + + } - switch_mutex_lock(member->conference->canvas_mutex); - if (member->video_layer_id > -1 && member->canvas_id > -1) { - canvas = member->conference->canvases[member->canvas_id]; - layer = &canvas->layers[member->video_layer_id]; + switch_frame_buffer_free(member->fb, &frame); + } - if (layer->need_patch) { - switch_mutex_lock(canvas->mutex); - } else { - canvas = NULL; - layer = NULL; - } - } - switch_mutex_unlock(member->conference->canvas_mutex); + switch_mutex_lock(member->conference->canvas_mutex); + if (member->video_layer_id > -1 && member->canvas_id > -1) { + canvas = member->conference->canvases[member->canvas_id]; + layer = &canvas->layers[member->video_layer_id]; - if (canvas) { - switch_thread_rwlock_rdlock(canvas->video_rwlock); - conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); - layer->need_patch = 0; - switch_thread_rwlock_unlock(canvas->video_rwlock); - switch_mutex_unlock(canvas->mutex); + if (layer->need_patch) { + switch_mutex_lock(canvas->mutex); + } else { + canvas = NULL; + layer = NULL; } } + switch_mutex_unlock(member->conference->canvas_mutex); + + if (canvas) { + switch_thread_rwlock_rdlock(canvas->video_rwlock); + conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); + layer->need_patch = 0; + switch_thread_rwlock_unlock(canvas->video_rwlock); + switch_mutex_unlock(canvas->mutex); + } } } @@ -1902,7 +1917,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN); while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) { - switch_bool_t need_refresh = SWITCH_FALSE, need_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; + switch_bool_t need_refresh = SWITCH_FALSE, send_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; switch_time_t now; int min_members = 0; int count_changed = 0; @@ -1970,7 +1985,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (count_changed) { need_refresh = 1; - need_keyframe = 1; + send_keyframe = 1; do_refresh = 100; } @@ -2030,7 +2045,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) && @@ -2220,7 +2235,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr conference_member_t *omember; if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2245,7 +2260,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (count_changed) { @@ -2418,7 +2433,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } @@ -2468,7 +2483,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr } if (layer->cur_img) { - if (layer->member) { + if (layer->member && switch_core_cpu_count() > 2) { layer->need_patch = 1; } else { conference_video_scale_and_patch(layer, NULL, SWITCH_FALSE); @@ -2510,14 +2525,14 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr if (canvas->send_keyframe > 0) { if (canvas->send_keyframe == 1 || (canvas->send_keyframe % 10) == 0) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; need_refresh = SWITCH_TRUE; } canvas->send_keyframe--; } if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2567,7 +2582,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { write_codecs[i]->frame.img = write_img; conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, - timestamp, need_refresh, need_keyframe, need_reset); + timestamp, need_refresh, send_keyframe, need_reset); if (canvas->video_write_bandwidth) { switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, @@ -2598,7 +2613,7 @@ void *SWITCH_THREAD_FUNC conference_video_muxing_thread_run(switch_thread_t *thr switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } @@ -2705,7 +2720,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ packet = switch_core_alloc(conference->pool, SWITCH_RTP_MAX_BUF_LEN); while (conference_globals.running && !conference_utils_test_flag(conference, CFLAG_DESTRUCT) && conference_utils_test_flag(conference, CFLAG_VIDEO_MUXING)) { - switch_bool_t need_refresh = SWITCH_FALSE, need_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; + switch_bool_t need_refresh = SWITCH_FALSE, send_keyframe = SWITCH_FALSE, need_reset = SWITCH_FALSE; switch_time_t now; int min_members = 0; int count_changed = 0; @@ -2739,14 +2754,14 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (canvas->send_keyframe > 0) { if (canvas->send_keyframe == 1 || (canvas->send_keyframe % 10) == 0) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; need_refresh = SWITCH_TRUE; } canvas->send_keyframe--; } if (video_key_freq && (now - last_key_time) > video_key_freq) { - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; last_key_time = now; } @@ -2790,7 +2805,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (imember->watching_canvas_id == canvas->canvas_id && switch_channel_test_flag(imember->channel, CF_VIDEO_REFRESH_REQ)) { switch_channel_clear_flag(imember->channel, CF_VIDEO_REFRESH_REQ); - need_keyframe = SWITCH_TRUE; + send_keyframe = SWITCH_TRUE; } if (conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING) && @@ -2910,7 +2925,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ if (min_members && conference_utils_test_flag(conference, CFLAG_MINIMIZE_VIDEO_ENCODING)) { for (i = 0; write_codecs[i] && switch_core_codec_ready(&write_codecs[i]->codec) && i < MAX_MUX_CODECS; i++) { write_codecs[i]->frame.img = write_img; - conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, timestamp, need_refresh, need_keyframe, need_reset); + conference_video_write_canvas_image_to_codec_group(conference, canvas, write_codecs[i], i, timestamp, need_refresh, send_keyframe, need_reset); if (canvas->video_write_bandwidth) { switch_core_codec_control(&write_codecs[i]->codec, SCC_VIDEO_BANDWIDTH, @@ -2943,7 +2958,7 @@ void *SWITCH_THREAD_FUNC conference_video_super_muxing_thread_run(switch_thread_ switch_core_session_request_video_refresh(imember->session); } - if (need_keyframe) { + if (send_keyframe) { switch_core_media_gen_key_frame(imember->session); } diff --git a/src/mod/codecs/mod_openh264/mod_openh264.cpp b/src/mod/codecs/mod_openh264/mod_openh264.cpp index e8ce3f5c69..723462b1f2 100644 --- a/src/mod/codecs/mod_openh264/mod_openh264.cpp +++ b/src/mod/codecs/mod_openh264/mod_openh264.cpp @@ -743,7 +743,7 @@ static switch_status_t switch_h264_control(switch_codec_t *codec, h264_codec_context_t *context = (h264_codec_context_t *)codec->private_info; switch(cmd) { - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/codecs/mod_vpx/mod_vpx.c b/src/mod/codecs/mod_vpx/mod_vpx.c index 0863e3f4f4..e1311b8f84 100644 --- a/src/mod/codecs/mod_vpx/mod_vpx.c +++ b/src/mod/codecs/mod_vpx/mod_vpx.c @@ -960,7 +960,7 @@ static switch_status_t switch_vpx_control(switch_codec_t *codec, } } break; - case SCC_VIDEO_REFRESH: + case SCC_VIDEO_GEN_KEYFRAME: context->need_key_frame = 1; break; case SCC_VIDEO_BANDWIDTH: diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index c0aa40c407..f94de19823 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -29739,7 +29739,7 @@ public class switch_chat_interface : IDisposable { namespace FreeSWITCH.Native { public enum switch_codec_control_command_t { - SCC_VIDEO_REFRESH = 0, + SCC_VIDEO_GEN_KEYFRAME = 0, SCC_VIDEO_BANDWIDTH, SCC_VIDEO_RESET, SCC_AUDIO_PACKET_LOSS, diff --git a/src/switch_core_media.c b/src/switch_core_media.c index fcce2da4c0..d24f8dc239 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -6164,9 +6164,9 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_activate_rtp(switch_core_sessi switch_core_media_parse_rtp_bugs(&a_engine->rtp_bugs, val); } - if (switch_channel_test_flag(session->channel, CF_AVPF)) { - smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS; - } + //if (switch_channel_test_flag(session->channel, CF_AVPF)) { + // smh->mparams->manual_rtp_bugs = RTP_BUG_SEND_LINEAR_TIMESTAMPS; + //} switch_rtp_intentional_bugs(a_engine->rtp_session, a_engine->rtp_bugs | smh->mparams->manual_rtp_bugs); @@ -10565,7 +10565,7 @@ SWITCH_DECLARE(switch_status_t) switch_core_media_codec_control(switch_core_sess } if (codec) { - if (cmd == SCC_VIDEO_REFRESH) { + if (cmd == SCC_VIDEO_GEN_KEYFRAME) { switch_time_t now = switch_micro_time_now(); if (smh->last_codec_refresh && (now - smh->last_codec_refresh) < VIDEO_REFRESH_FREQ) { diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index a099884b61..cce4535760 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -37,7 +37,7 @@ #define PERIOD_LEN 500 #define MAX_FRAME_PADDING 2 #define MAX_MISSING_SEQ 20 -#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%d sz:%u/%u/%u c:%u %u/%u/%u/%u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__) +#define jb_debug(_jb, _level, _format, ...) if (_jb->debug_level >= _level) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG_CLEAN(_jb->session), SWITCH_LOG_ALERT, "JB:%p:%s lv:%d ln:%d sz:%u/%u/%u/%u c:%u %u/%u/%u/%u %.2f%% ->" _format, (void *) _jb, (jb->type == SJB_AUDIO ? "aud" : "vid"), _level, __LINE__, _jb->min_frame_len, _jb->max_frame_len, _jb->frame_len, _jb->visible_nodes, _jb->period_count, _jb->consec_good_count, _jb->period_good_count, _jb->consec_miss_count, _jb->period_miss_count, _jb->period_miss_pct, __VA_ARGS__) //const char *TOKEN_1 = "ONE"; //const char *TOKEN_2 = "TWO"; @@ -1024,13 +1024,6 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb) return nack; } -SWITCH_DECLARE(switch_status_t) switch_jb_push_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) -{ - add_node(jb, packet, len); - - return SWITCH_STATUS_SUCCESS; -} - SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) { uint32_t i; @@ -1081,6 +1074,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp } add_node(jb, packet, len); + + if (switch_test_flag(jb, SJB_QUEUE_ONLY) && jb->complete_frames > jb->max_frame_len) { + drop_oldest_frame(jb); + } switch_mutex_unlock(jb->mutex); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 8f4dc6f165..6f4f8bec8c 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -7306,9 +7306,12 @@ static int rtp_common_write(switch_rtp_t *rtp_session, if (rtp_session->flags[SWITCH_RTP_FLAG_NACK]) { if (!rtp_session->vbw) { switch_jb_create(&rtp_session->vbw, SJB_VIDEO, 30, 30, rtp_session->pool); - //switch_jb_debug_level(rtp_session->vbw, 10); + if (rtp_session->vbw) { + switch_jb_set_flag(rtp_session->vbw, SJB_QUEUE_ONLY); + //switch_jb_debug_level(rtp_session->vbw, 10); + } } - switch_jb_push_packet(rtp_session->vbw, (switch_rtp_packet_t *)send_msg, bytes); + switch_jb_put_packet(rtp_session->vbw, (switch_rtp_packet_t *)send_msg, bytes); } #ifdef RTP_WRITE_PLOSS