FS-8179 #resolve [mod_opus: improvement on new JB buffer debugging (debug lookahead FEC)]

This commit is contained in:
Anthony Minessale 2015-10-01 19:11:51 -05:00
parent 7b4c5a863e
commit ead42d56b5
3 changed files with 71 additions and 16 deletions

View File

@ -78,6 +78,8 @@ struct opus_context {
uint32_t debug; uint32_t debug;
uint32_t use_jb_lookahead; uint32_t use_jb_lookahead;
opus_codec_settings_t codec_settings; opus_codec_settings_t codec_settings;
int look_check;
int look_ts;
}; };
struct { struct {
@ -610,6 +612,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
if (*flag & SFF_PLC) { if (*flag & SFF_PLC) {
switch_core_session_t *session = codec->session; switch_core_session_t *session = codec->session;
switch_channel_t *channel = switch_core_session_get_channel(session);
switch_jb_t *jb = NULL; switch_jb_t *jb = NULL;
int got_frame = 0; int got_frame = 0;
@ -618,20 +621,40 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
encoded_data = NULL; encoded_data = NULL;
if ((opus_prefs.use_jb_lookahead || context->use_jb_lookahead) && context->codec_settings.useinbandfec && session) { if ((opus_prefs.use_jb_lookahead || context->use_jb_lookahead) && context->codec_settings.useinbandfec && session) {
if (opus_packet_get_bandwidth(codec->cur_frame->data) != OPUS_BANDWIDTH_FULLBAND && if (!context->look_check) {
codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) { context->look_ts = switch_true(switch_channel_get_variable_dup(channel, "jb_use_timestamps", SWITCH_FALSE, -1));
context->look_check = 1;
}
if (codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) {
switch_frame_t frame = { 0 }; switch_frame_t frame = { 0 };
uint8_t buf[SWITCH_RTP_MAX_BUF_LEN]; uint8_t buf[SWITCH_RTP_MAX_BUF_LEN];
uint32_t ts = 0;
uint16_t seq = 0;
if (context->look_ts) {
ts = codec->cur_frame->timestamp;
} else {
seq = codec->cur_frame->seq;
}
frame.data = buf; frame.data = buf;
frame.buflen = sizeof(buf); frame.buflen = sizeof(buf);
if (switch_jb_peek_frame(jb, ts, seq, 1, &frame) == SWITCH_STATUS_SUCCESS) {
if (globals.debug || context->debug) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Lookahead frame found: %u -> %u\n",
codec->cur_frame->timestamp, frame.timestamp);
}
if (switch_jb_peek_frame(jb, codec->cur_frame->timestamp, 0, 1, &frame)) {
got_frame = 1;
fec = 1;
encoded_data = frame.data; encoded_data = frame.data;
encoded_data_len = frame.datalen; encoded_data_len = frame.datalen;
if ((fec = switch_opus_has_fec(frame.data, frame.datalen))) {
got_frame = 1;
}
if (globals.debug || context->debug) { if (globals.debug || context->debug) {
if (switch_opus_has_fec(frame.data, frame.datalen)) { if (fec) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ[%d] encoded_data_len: %d\n", switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "FEC info available in packet with SEQ[%d] encoded_data_len: %d\n",
codec->cur_frame->seq, encoded_data_len); codec->cur_frame->seq, encoded_data_len);
} else { } else {
@ -639,7 +662,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
codec->cur_frame->seq, encoded_data_len ); codec->cur_frame->seq, encoded_data_len );
} }
} }
} }
} }
} }
@ -784,6 +807,13 @@ static switch_status_t opus_load_config(switch_bool_t reload)
return status; return status;
} }
memset(&opus_prefs, 0, sizeof(opus_prefs));
opus_prefs.use_jb_lookahead = 1;
opus_prefs.keep_fec = 1;
opus_prefs.use_dtx = 1;
opus_prefs.plpct = 20;
opus_prefs.use_vbr = 1;
if ((settings = switch_xml_child(cfg, "settings"))) { if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) { for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *key = (char *) switch_xml_attr_soft(param, "name"); char *key = (char *) switch_xml_attr_soft(param, "name");

View File

@ -65,6 +65,7 @@ struct switch_jb_s {
uint32_t target_ts; uint32_t target_ts;
uint32_t last_target_ts; uint32_t last_target_ts;
uint16_t psuedo_seq; uint16_t psuedo_seq;
uint16_t last_psuedo_seq;
uint32_t visible_nodes; uint32_t visible_nodes;
uint32_t complete_frames; uint32_t complete_frames;
uint32_t frame_len; uint32_t frame_len;
@ -581,6 +582,8 @@ static inline void increment_ts(switch_jb_t *jb)
{ {
if (!jb->target_ts) return; if (!jb->target_ts) return;
jb->last_psuedo_seq = jb->psuedo_seq;
jb->last_target_ts = jb->target_ts;
jb->target_ts = htonl((ntohl(jb->target_ts) + jb->samples_per_frame)); jb->target_ts = htonl((ntohl(jb->target_ts) + jb->samples_per_frame));
jb->psuedo_seq++; jb->psuedo_seq++;
} }
@ -589,6 +592,7 @@ static inline void set_read_ts(switch_jb_t *jb, uint32_t ts)
{ {
if (!ts) return; if (!ts) return;
jb->last_psuedo_seq = jb->psuedo_seq;
jb->last_target_ts = ts; jb->last_target_ts = ts;
jb->target_ts = htonl((ntohl(jb->last_target_ts) + jb->samples_per_frame)); jb->target_ts = htonl((ntohl(jb->last_target_ts) + jb->samples_per_frame));
jb->psuedo_seq++; jb->psuedo_seq++;
@ -597,6 +601,7 @@ static inline void set_read_ts(switch_jb_t *jb, uint32_t ts)
static inline void increment_seq(switch_jb_t *jb) static inline void increment_seq(switch_jb_t *jb)
{ {
jb->last_target_seq = jb->target_seq;
jb->target_seq = htons((ntohs(jb->target_seq) + 1)); jb->target_seq = htons((ntohs(jb->target_seq) + 1));
} }
@ -828,13 +833,12 @@ SWITCH_DECLARE(void) switch_jb_reset(switch_jb_t *jb)
SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame) SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t ts, uint16_t seq, int peek, switch_frame_t *frame)
{ {
switch_jb_node_t *node = NULL; switch_jb_node_t *node = NULL;
if (seq) { if (seq) {
uint16_t want_seq = seq + peek; uint16_t want_seq = seq + peek;
node = switch_core_inthash_find(jb->node_hash, want_seq); node = switch_core_inthash_find(jb->node_hash, htons(want_seq));
} else if (ts && jb->samples_per_frame) { } else if (ts && jb->samples_per_frame) {
uint32_t want_ts = ts + (peek * jb->samples_per_frame); uint32_t want_ts = ts + (peek * jb->samples_per_frame);
node = switch_core_inthash_find(jb->node_hash_ts, want_ts); node = switch_core_inthash_find(jb->node_hash_ts, htonl(want_ts));
} }
if (node) { if (node) {
@ -842,6 +846,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_peek_frame(switch_jb_t *jb, uint32_t t
frame->timestamp = ntohl(node->packet.header.ts); frame->timestamp = ntohl(node->packet.header.ts);
frame->m = node->packet.header.m; frame->m = node->packet.header.m;
frame->datalen = node->len; frame->datalen = node->len;
if (frame->data && frame->buflen > node->len) { if (frame->data && frame->buflen > node->len) {
memcpy(frame->data, node->packet.body, node->len); memcpy(frame->data, node->packet.body, node->len);
} }
@ -1129,7 +1134,8 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
{ {
switch_jb_node_t *node = NULL; switch_jb_node_t *node = NULL;
switch_status_t status; switch_status_t status;
int plc = 0;
switch_mutex_lock(jb->mutex); switch_mutex_lock(jb->mutex);
if (jb->complete_frames < jb->frame_len) { if (jb->complete_frames < jb->frame_len) {
@ -1230,6 +1236,7 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
switch_goto_status(SWITCH_STATUS_RESTART, end); switch_goto_status(SWITCH_STATUS_RESTART, end);
} else { } else {
jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n"); jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n");
plc = 1;
switch_goto_status(SWITCH_STATUS_NOTFOUND, end); switch_goto_status(SWITCH_STATUS_NOTFOUND, end);
} }
} }
@ -1253,6 +1260,22 @@ SWITCH_DECLARE(switch_status_t) switch_jb_get_packet(switch_jb_t *jb, switch_rtp
end: end:
if (plc) {
uint16_t seq;
uint32_t ts;
if (jb->samples_per_frame) {
seq = htons(jb->last_psuedo_seq);
} else {
seq = jb->last_target_seq;
}
ts = jb->last_target_ts;
packet->header.seq = seq;
packet->header.ts = ts
}
switch_mutex_unlock(jb->mutex); switch_mutex_unlock(jb->mutex);
if (status == SWITCH_STATUS_SUCCESS && jb->type == SJB_AUDIO) { if (status == SWITCH_STATUS_SUCCESS && jb->type == SJB_AUDIO) {

View File

@ -4059,7 +4059,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
} else { } else {
status = switch_jb_create(&rtp_session->jb, SJB_AUDIO, queue_frames, max_queue_frames, rtp_session->pool); status = switch_jb_create(&rtp_session->jb, SJB_AUDIO, queue_frames, max_queue_frames, rtp_session->pool);
switch_jb_set_session(rtp_session->jb, rtp_session->session); switch_jb_set_session(rtp_session->jb, rtp_session->session);
switch_jb_ts_mode(rtp_session->jb, samples_per_packet, samples_per_second); if (switch_true(switch_channel_get_variable_dup(switch_core_session_get_channel(rtp_session->session), "jb_use_timestamps", SWITCH_FALSE, -1))) {
switch_jb_ts_mode(rtp_session->jb, samples_per_packet, samples_per_second);
}
//switch_jb_debug_level(rtp_session->jb, 10); //switch_jb_debug_level(rtp_session->jb, 10);
} }
@ -5459,8 +5461,8 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
{ {
(*flags) |= SFF_PLC; (*flags) |= SFF_PLC;
status = SWITCH_STATUS_SUCCESS; status = SWITCH_STATUS_SUCCESS;
rtp_session->recv_msg.header = rtp_session->last_rtp_hdr;
*bytes = switch_jb_get_last_read_len(rtp_session->jb); *bytes = switch_jb_get_last_read_len(rtp_session->jb);
rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
} }
break; break;
case SWITCH_STATUS_SUCCESS: case SWITCH_STATUS_SUCCESS:
@ -6803,10 +6805,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_zerocopy_read_frame(switch_rtp_t *rtp
if (frame->payload == rtp_session->recv_te) { if (frame->payload == rtp_session->recv_te) {
switch_set_flag(frame, SFF_RFC2833); switch_set_flag(frame, SFF_RFC2833);
} }
frame->timestamp = ntohl(rtp_session->recv_msg.header.ts); frame->timestamp = ntohl(rtp_session->last_rtp_hdr.ts);
frame->seq = (uint16_t) ntohs((uint16_t) rtp_session->recv_msg.header.seq); frame->seq = (uint16_t) ntohs((uint16_t) rtp_session->last_rtp_hdr.seq);
frame->ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc); frame->ssrc = ntohl(rtp_session->last_rtp_hdr.ssrc);
frame->m = rtp_session->recv_msg.header.m ? SWITCH_TRUE : SWITCH_FALSE; frame->m = rtp_session->last_rtp_hdr.m ? SWITCH_TRUE : SWITCH_FALSE;
} }
#ifdef ENABLE_ZRTP #ifdef ENABLE_ZRTP