From 4a56b7d1455c98b69c0b893388c5bbd1f8f798d6 Mon Sep 17 00:00:00 2001 From: Anthony Minessale Date: Thu, 17 Sep 2015 17:34:50 -0500 Subject: [PATCH] FS-8130 cont --- .../mod_conference/conference_video.c | 6 +- src/switch_core_media.c | 2 +- src/switch_jitterbuffer.c | 115 ++++++++++++------ src/switch_rtp.c | 55 ++++++--- 4 files changed, 122 insertions(+), 56 deletions(-) diff --git a/src/mod/applications/mod_conference/conference_video.c b/src/mod/applications/mod_conference/conference_video.c index 8789e6e93d..07dc306d2c 100644 --- a/src/mod/applications/mod_conference/conference_video.c +++ b/src/mod/applications/mod_conference/conference_video.c @@ -1814,8 +1814,10 @@ void conference_video_pop_next_image(conference_member_t *member, switch_image_t void conference_video_check_auto_bitrate(conference_member_t *member, mcu_layer_t *layer) { - if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps && - !switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) { + + if (switch_channel_test_flag(member->channel, CF_VIDEO_BITRATE_UNMANAGABLE)) { + member->managed_kps = 0; + } else if (conference_utils_test_flag(member->conference, CFLAG_MANAGE_INBOUND_VIDEO_BITRATE) && !member->managed_kps) { switch_core_session_message_t msg = { 0 }; int kps; int w = 320; diff --git a/src/switch_core_media.c b/src/switch_core_media.c index 4c7456ad2f..892d8c0919 100644 --- a/src/switch_core_media.c +++ b/src/switch_core_media.c @@ -2014,7 +2014,7 @@ static void check_jb_sync(switch_core_session_t *session) switch_rtp_get_video_buffer_size(v_engine->rtp_session, &min_frames, &max_frames, &cur_frames, NULL); - if (cur_frames > min_frames || frames == min_frames) { + if (frames == cur_frames) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG1, "%s %s \"%s\" A/V JB not changed %dms %u VFrames FPS %u\n", switch_core_session_get_uuid(session), diff --git a/src/switch_jitterbuffer.c b/src/switch_jitterbuffer.c index c236743dab..e9e31793d6 100644 --- a/src/switch_jitterbuffer.c +++ b/src/switch_jitterbuffer.c @@ -78,6 +78,7 @@ struct switch_jb_s { uint32_t dropped; uint32_t samples_per_frame; uint32_t samples_per_second; + uint32_t bitrate_control; uint8_t write_init; uint8_t read_init; uint8_t debug_level; @@ -375,6 +376,31 @@ static inline uint32_t jb_find_lowest_ts(switch_jb_t *jb) return lowest ? lowest->packet.header.ts : 0; } + +static inline switch_jb_node_t *jb_find_highest_node(switch_jb_t *jb) +{ + switch_jb_node_t *np, *highest = NULL; + + switch_mutex_lock(jb->list_mutex); + for (np = jb->node_list; np; np = np->next) { + if (!np->visible) continue; + + if (!highest || ntohl(highest->packet.header.ts) < ntohl(np->packet.header.ts)) { + highest = np; + } + } + switch_mutex_unlock(jb->list_mutex); + + return highest ? highest : NULL; +} + +static inline uint32_t jb_find_highest_ts(switch_jb_t *jb) +{ + switch_jb_node_t *highest = jb_find_highest_node(jb); + + return highest ? highest->packet.header.ts : 0; +} + static inline void jb_hit(switch_jb_t *jb) { jb->period_good_count++; @@ -382,7 +408,7 @@ static inline void jb_hit(switch_jb_t *jb) jb->consec_miss_count = 0; } -static void jb_frame_inc(switch_jb_t *jb, int i) +static void jb_frame_inc_line(switch_jb_t *jb, int i, int line) { uint32_t old_frame_len = jb->frame_len; @@ -415,34 +441,37 @@ static void jb_frame_inc(switch_jb_t *jb, int i) jb->highest_frame_len = jb->frame_len; } - if (jb->type == SJB_VIDEO && (jb->frame_len > jb->min_frame_len || jb->frame_len == jb->min_frame_len)) { - if (jb->channel) { - if (jb->frame_len == jb->min_frame_len) { - jb_debug(jb, 2, "%s", "Allow BITRATE changes\n"); - switch_channel_clear_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); - } else { - switch_core_session_message_t msg = { 0 }; - int new_bitrate = 512; + if (jb->type == SJB_VIDEO && jb->channel) { + int ok = (jb->frame_len <= jb->min_frame_len + 1); + + if (switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && ok) { + jb_debug(jb, 2, "%s", "Allow BITRATE changes\n"); + switch_channel_clear_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); + jb->bitrate_control = 0; + } else if (!ok) { + switch_core_session_message_t msg = { 0 }; + jb->bitrate_control = 512; - msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ; - msg.numeric_arg = new_bitrate * 1024; - msg.from = __FILE__; + msg.message_id = SWITCH_MESSAGE_INDICATE_BITRATE_REQ; + msg.numeric_arg = jb->bitrate_control * 1024; + msg.from = __FILE__; - jb_debug(jb, 2, "Force BITRATE to %d\n", new_bitrate); - switch_core_session_receive_message(jb->session, &msg); - - switch_channel_set_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); + jb_debug(jb, 2, "Force BITRATE to %d\n", jb->bitrate_control); + switch_core_session_receive_message(jb->session, &msg); + switch_channel_set_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE); - } } } if (old_frame_len != jb->frame_len) { - jb_debug(jb, 2, "Change framelen from %u to %u\n", old_frame_len, jb->frame_len); + jb_debug(jb, 2, "%d Change framelen from %u to %u\n", line, old_frame_len, jb->frame_len); } } +#define jb_frame_inc(_jb, _i) jb_frame_inc_line(_jb, _i, __LINE__) + + static inline void jb_miss(switch_jb_t *jb) { jb->period_miss_count++; @@ -496,6 +525,14 @@ static inline void drop_oldest_frame(switch_jb_t *jb) jb_debug(jb, 1, "Dropping oldest frame ts:%u\n", ntohl(ts)); } +static inline void drop_newest_frame(switch_jb_t *jb) +{ + uint32_t ts = jb_find_highest_ts(jb); + + drop_ts(jb, ts); + jb_debug(jb, 1, "Dropping highest frame ts:%u\n", ntohl(ts)); +} + static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch_size_t len) { switch_jb_node_t *node = new_node(jb); @@ -513,19 +550,15 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch jb_debug(jb, (packet->header.m ? 1 : 2), "PUT packet last_ts:%u ts:%u seq:%u%s\n", ntohl(jb->highest_wrote_ts), ntohl(node->packet.header.ts), ntohs(node->packet.header.seq), packet->header.m ? " " : ""); - - - - - if (jb->write_init && ((abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))) >= jb->max_frame_len) || - (abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts))) > (900000 * 5)))) { - jb_debug(jb, 2, "%s", "CHANGE DETECTED, PUNT\n"); - switch_jb_reset(jb); - } + //if (jb->write_init && ((abs(((int)ntohs(packet->header.seq) - ntohs(jb->highest_wrote_seq))) >= jb->max_frame_len) || + //(abs((int)((int64_t)ntohl(node->packet.header.ts) - (int64_t)ntohl(jb->highest_wrote_ts))) > (900000 * 5)))) { + //jb_debug(jb, 2, "%s", "CHANGE DETECTED, PUNT\n"); + //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "%s Jitter Buffer anomoly, max size may be too small...\n", + //jb->type == SJB_AUDIO ? "Audio" : "Video"); + //switch_jb_reset(jb); + + //} - - - if (!jb->write_init || ntohs(packet->header.seq) > ntohs(jb->highest_wrote_seq) || (ntohs(jb->highest_wrote_seq) > USHRT_MAX - 10 && ntohs(packet->header.seq) <= 10) ) { jb->highest_wrote_seq = packet->header.seq; @@ -550,10 +583,6 @@ static inline void add_node(switch_jb_t *jb, switch_rtp_packet_t *packet, switch } if (!jb->write_init) jb->write_init = 1; - - if (jb->complete_frames > jb->max_frame_len + MAX_FRAME_PADDING) { - drop_oldest_frame(jb); - } } static inline void increment_ts(switch_jb_t *jb) @@ -834,7 +863,12 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_frames(switch_jb_t *jb, uint32_t * SWITCH_DECLARE(switch_status_t) switch_jb_set_frames(switch_jb_t *jb, uint32_t min_frame_len, uint32_t max_frame_len) { + int lowest = 0; + switch_mutex_lock(jb->mutex); + + if (jb->frame_len == jb->min_frame_len) lowest = 1; + jb->min_frame_len = min_frame_len; jb->max_frame_len = max_frame_len; @@ -850,6 +884,10 @@ SWITCH_DECLARE(switch_status_t) switch_jb_set_frames(switch_jb_t *jb, uint32_t m jb->highest_frame_len = jb->frame_len; } + if (lowest) { + jb->frame_len = jb->min_frame_len; + } + switch_mutex_unlock(jb->mutex); return SWITCH_STATUS_SUCCESS; @@ -1052,13 +1090,14 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp switch_status_t status; switch_mutex_lock(jb->mutex); - jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes); if (jb->complete_frames < jb->frame_len) { jb_debug(jb, 2, "BUFFERING %u/%u\n", jb->complete_frames , jb->frame_len); switch_goto_status(SWITCH_STATUS_MORE_DATA, end); } + jb_debug(jb, 2, "GET PACKET %u/%u n:%d\n", jb->complete_frames , jb->frame_len, jb->visible_nodes); + if (++jb->period_count >= PERIOD_LEN) { if (jb->consec_good_count >= (PERIOD_LEN - 5)) { @@ -1145,6 +1184,12 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp switch_mutex_unlock(jb->mutex); + if (status == SWITCH_STATUS_SUCCESS) { + if (jb->complete_frames > jb->max_frame_len) { + drop_oldest_frame(jb); + } + } + return status; } diff --git a/src/switch_rtp.c b/src/switch_rtp.c index c29e68e685..fda95be2f5 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -5406,16 +5406,22 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t switch_jb_put_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, *bytes); status = SWITCH_STATUS_FALSE; *bytes = 0; + + if (!return_jb_packet) { + return status; + } } if (rtp_session->jb && jb_valid(rtp_session)) { uint32_t read_ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); + if (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)) { switch_jb_reset(rtp_session->jb); } else if (rtp_session->last_jb_read_ssrc && rtp_session->last_jb_read_ssrc != read_ssrc) { switch_jb_reset(rtp_session->jb); } + rtp_session->last_jb_read_ssrc = read_ssrc; if (!rtp_session->flags[SWITCH_RTP_FLAG_USE_TIMER] && rtp_session->timer.interval) { @@ -5439,23 +5445,36 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t if (rtp_session->jb && !rtp_session->pause_jb && jb_valid(rtp_session)) { switch_status_t jstatus = switch_jb_get_packet(rtp_session->jb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); - if (jstatus == SWITCH_STATUS_NOTFOUND) { - (*flags) |= SFF_PLC; - status = SWITCH_STATUS_SUCCESS; - rtp_session->recv_msg.header = rtp_session->last_rtp_hdr; - *bytes = switch_jb_get_last_read_len(rtp_session->jb); - } else if (jstatus == SWITCH_STATUS_SUCCESS) { - rtp_session->stats.inbound.jb_packet_count++; - status = SWITCH_STATUS_SUCCESS; - rtp_session->last_rtp_hdr = rtp_session->recv_msg.header; + status = jstatus; - if (!xcheck_jitter) { - check_jitter(rtp_session); - xcheck_jitter = *bytes; + switch(jstatus) { + case SWITCH_STATUS_MORE_DATA: + status = SWITCH_STATUS_BREAK; + break; + case SWITCH_STATUS_NOTFOUND: + { + (*flags) |= SFF_PLC; + status = SWITCH_STATUS_SUCCESS; + rtp_session->recv_msg.header = rtp_session->last_rtp_hdr; + *bytes = switch_jb_get_last_read_len(rtp_session->jb); } + break; + case SWITCH_STATUS_SUCCESS: + default: + { + rtp_session->stats.inbound.jb_packet_count++; + status = SWITCH_STATUS_SUCCESS; + rtp_session->last_rtp_hdr = rtp_session->recv_msg.header; + + if (!xcheck_jitter) { + check_jitter(rtp_session); + xcheck_jitter = *bytes; + } + } + break; } } - + if (rtp_session->vb && jb_valid(rtp_session)) { switch_status_t vstatus = switch_jb_get_packet(rtp_session->vb, (switch_rtp_packet_t *) &rtp_session->recv_msg, bytes); status = vstatus; @@ -5927,11 +5946,11 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ read_pretriggered = 0; goto rtcp; } - - if (status != SWITCH_STATUS_FALSE) { - read_pretriggered = 1; - break; - } + + //if (status != SWITCH_STATUS_FALSE) { + // read_pretriggered = 1; + // break; + //} } } else if ((rtp_session->flags[SWITCH_RTP_FLAG_AUTOFLUSH] || rtp_session->flags[SWITCH_RTP_FLAG_STICKY_FLUSH])) {