forked from Mirrors/freeswitch
FS-8130 the bug that keeps on bugging, improve video nack
This commit is contained in:
parent
0fa190093e
commit
6f0bbeec28
@ -37,8 +37,8 @@
|
||||
#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__)
|
||||
|
||||
const char *TOKEN_1 = "ONE";
|
||||
const char *TOKEN_2 = "TWO";
|
||||
//const char *TOKEN_1 = "ONE";
|
||||
//const char *TOKEN_2 = "TWO";
|
||||
|
||||
struct switch_jb_s;
|
||||
|
||||
@ -71,6 +71,7 @@ struct switch_jb_s {
|
||||
uint32_t highest_frame_len;
|
||||
uint32_t period_miss_count;
|
||||
uint32_t consec_miss_count;
|
||||
uint32_t period_miss_inc;
|
||||
double period_miss_pct;
|
||||
uint32_t period_good_count;
|
||||
uint32_t consec_good_count;
|
||||
@ -485,7 +486,7 @@ static inline int verify_oldest_frame(switch_jb_t *jb)
|
||||
uint32_t val = (uint32_t)htons(ntohs(np->prev->packet.header.seq) + 1);
|
||||
|
||||
if (!switch_core_inthash_find(jb->missing_seq_hash, val)) {
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, val, (void *) TOKEN_1);
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, val, (void *) (intptr_t) 1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -634,7 +635,10 @@ static inline switch_status_t jb_next_packet_by_seq(switch_jb_t *jb, switch_jb_n
|
||||
if (jb->type == SJB_VIDEO) {
|
||||
int x;
|
||||
|
||||
jb_frame_inc(jb, 1);
|
||||
if (jb->period_miss_count > 1 && !jb->period_miss_inc) {
|
||||
jb->period_miss_inc++;
|
||||
jb_frame_inc(jb, 1);
|
||||
}
|
||||
|
||||
//if (jb->session) {
|
||||
// switch_core_session_request_video_refresh(jb->session);
|
||||
@ -795,6 +799,7 @@ SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb)
|
||||
jb->period_good_count = 0;
|
||||
jb->consec_good_count = 0;
|
||||
jb->period_count = 0;
|
||||
jb->period_miss_inc = 0;
|
||||
jb->target_ts = 0;
|
||||
jb->last_target_ts = 0;
|
||||
|
||||
@ -942,9 +947,8 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
switch_hash_index_t *hi = NULL;
|
||||
uint32_t nack = 0;
|
||||
uint16_t blp = 0;
|
||||
uint16_t most = 0;
|
||||
uint16_t least = 0;
|
||||
int i = 0;
|
||||
|
||||
void *val;
|
||||
const void *var;
|
||||
|
||||
@ -954,42 +958,54 @@ SWITCH_DECLARE(uint32_t) switch_jb_pop_nack(switch_jb_t *jb)
|
||||
|
||||
switch_mutex_lock(jb->mutex);
|
||||
|
||||
top:
|
||||
|
||||
for (hi = switch_core_hash_first(jb->missing_seq_hash); hi; hi = switch_core_hash_next(&hi)) {
|
||||
uint16_t seq;
|
||||
const char *token;
|
||||
uint32_t ts;
|
||||
|
||||
//const char *token;
|
||||
switch_time_t then = 0;
|
||||
|
||||
switch_core_hash_this(hi, &var, NULL, &val);
|
||||
token = (const char *) val;
|
||||
//token = (const char *) val;
|
||||
|
||||
if (token == TOKEN_2) {
|
||||
//if (token == TOKEN_2) {
|
||||
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SKIP %u %s\n", ntohs(*((uint16_t *) var)), token);
|
||||
//printf("WTf\n");
|
||||
continue;
|
||||
}
|
||||
|
||||
ts = (intptr_t)val;
|
||||
|
||||
if (ts == jb->highest_wrote_ts) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// continue;
|
||||
//}
|
||||
|
||||
seq = ntohs(*((uint16_t *) var));
|
||||
then = (intptr_t) val;
|
||||
|
||||
if (!most || seq > most) {
|
||||
most = seq;
|
||||
if (then != 1 && switch_time_now() - then < 100000) {
|
||||
//jb_debug(jb, 3, "NACKABLE seq %u too soon to repeat\n", seq);
|
||||
continue;
|
||||
}
|
||||
|
||||
//if (then != 1) {
|
||||
// jb_debug(jb, 3, "NACKABLE seq %u not too soon to repeat %lu\n", seq, switch_time_now() - then);
|
||||
//}
|
||||
|
||||
if (seq < ntohs(jb->target_seq) - jb->frame_len) {
|
||||
jb_debug(jb, 3, "NACKABLE seq %u expired\n", seq);
|
||||
switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(seq));
|
||||
goto top;
|
||||
}
|
||||
|
||||
if (!least || seq < least) {
|
||||
least = seq;
|
||||
}
|
||||
}
|
||||
|
||||
if (most && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(most))) {
|
||||
jb_debug(jb, 3, "Found NACKABLE seq %u\n", most);
|
||||
nack = (uint32_t) htons(most);
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) TOKEN_2);
|
||||
if (least && switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least))) {
|
||||
jb_debug(jb, 3, "Found NACKABLE seq %u\n", least);
|
||||
nack = (uint32_t) htons(least);
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, nack, (void *) (intptr_t)switch_time_now());
|
||||
|
||||
for(i = 0; i < 16; i++) {
|
||||
if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(most + i + 1))) {
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(most + i + 1), (void *) TOKEN_2);
|
||||
jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", most + i + 1);
|
||||
if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(least + i + 1))) {
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(least + i + 1), (void *)(intptr_t)switch_time_now());
|
||||
jb_debug(jb, 3, "Found addtl NACKABLE seq %u\n", least + i + 1);
|
||||
blp |= (1 << i);
|
||||
}
|
||||
}
|
||||
@ -1026,7 +1042,14 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
||||
jb->next_seq = htons(got + 1);
|
||||
} else {
|
||||
|
||||
switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got));
|
||||
if (switch_core_inthash_delete(jb->missing_seq_hash, (uint32_t)htons(got))) {
|
||||
if (got < ntohs(jb->target_seq)) {
|
||||
jb_debug(jb, 2, "got nacked seq %u too late\n", got);
|
||||
jb_frame_inc(jb, 1);
|
||||
} else {
|
||||
jb_debug(jb, 2, "got nacked %u saved the day!\n", got);
|
||||
}
|
||||
}
|
||||
|
||||
if (got > want) {
|
||||
if (got - want > jb->max_frame_len && got - want > 17) {
|
||||
@ -1036,11 +1059,16 @@ SWITCH_DECLARE(switch_status_t) switch_jb_put_packet(switch_jb_t *jb, switch_rtp
|
||||
switch_core_session_request_video_refresh(jb->session);
|
||||
}
|
||||
} else {
|
||||
|
||||
if (jb->frame_len < got - want) {
|
||||
jb_frame_inc(jb, got - want - jb->frame_len);
|
||||
}
|
||||
|
||||
jb_debug(jb, 2, "GOT %u WANTED %u; MARK SEQS MISSING %u - %u\n", got, want, want, got - 1);
|
||||
|
||||
for (i = want; i < got; i++) {
|
||||
jb_debug(jb, 2, "MARK MISSING %u ts:%u\n", i, ntohl(packet->header.ts));
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *)(intptr_t)packet->header.ts);
|
||||
switch_core_inthash_insert(jb->missing_seq_hash, (uint32_t)htons(i), (void *) (intptr_t) 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1104,13 +1132,14 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
}
|
||||
|
||||
jb->period_count = 1;
|
||||
jb->period_miss_inc = 0;
|
||||
jb->period_miss_count = 0;
|
||||
jb->period_good_count = 0;
|
||||
jb->consec_miss_count = 0;
|
||||
jb->consec_good_count = 0;
|
||||
|
||||
#if 0
|
||||
if (jb->type == SJB_VIDEO && jb->channel) {
|
||||
//switch_time_t now = switch_micro_time_now();
|
||||
//switch_time_t now = switch_time_now();
|
||||
//int ok = (now - jb->last_bitrate_change) > 10000;
|
||||
|
||||
if (switch_channel_test_flag(jb->channel, CF_VIDEO_BITRATE_UNMANAGABLE) && jb->frame_len == jb->min_frame_len) {
|
||||
@ -1132,6 +1161,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
jb->period_miss_pct = ((double)jb->period_miss_count / jb->period_count) * 100;
|
||||
|
@ -1895,7 +1895,7 @@ static int using_ice(switch_rtp_t *rtp_session)
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define MAX_NACK 1
|
||||
#define MAX_NACK 10
|
||||
static int check_rtcp_and_ice(switch_rtp_t *rtp_session)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -3995,7 +3995,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_set_video_buffer_size(switch_rtp_t *r
|
||||
}
|
||||
|
||||
if (!max_frames) {
|
||||
max_frames = frames * 4;
|
||||
max_frames = 40;
|
||||
}
|
||||
|
||||
if (!rtp_session->vb) {
|
||||
@ -5395,9 +5395,14 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
|
||||
|
||||
if (rtp_session->flags[SWITCH_RTP_FLAG_KILL_JB]) {
|
||||
rtp_session->flags[SWITCH_RTP_FLAG_KILL_JB] = 0;
|
||||
|
||||
if (rtp_session->jb) {
|
||||
switch_jb_destroy(&rtp_session->jb);
|
||||
}
|
||||
|
||||
if (rtp_session->vb) {
|
||||
switch_jb_destroy(&rtp_session->vb);
|
||||
}
|
||||
}
|
||||
|
||||
if (rtp_session->recv_msg.header.version == 2 && *bytes) {
|
||||
@ -7300,7 +7305,7 @@ 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, 10, 10, rtp_session->pool);
|
||||
switch_jb_create(&rtp_session->vbw, SJB_VIDEO, 30, 30, rtp_session->pool);
|
||||
//switch_jb_debug_level(rtp_session->vbw, 10);
|
||||
}
|
||||
switch_jb_push_packet(rtp_session->vbw, (switch_rtp_packet_t *)send_msg, bytes);
|
||||
|
Loading…
Reference in New Issue
Block a user