]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
FS-8179 #resolve [mod_opus: improvement on new JB buffer debugging (debug lookahead...
authorAnthony Minessale <anthm@freeswitch.org>
Fri, 2 Oct 2015 00:11:51 +0000 (19:11 -0500)
committerAnthony Minessale <anthm@freeswitch.org>
Fri, 2 Oct 2015 00:12:03 +0000 (19:12 -0500)
src/mod/codecs/mod_opus/mod_opus.c
src/switch_jitterbuffer.c
src/switch_rtp.c

index 0872089269a04190802f5dd7359e0de1582e9f8b..c30cd66a63ba0068e7ec5bede7acc7fde900500d 100644 (file)
@@ -78,6 +78,8 @@ struct opus_context {
        uint32_t debug;
        uint32_t use_jb_lookahead;
        opus_codec_settings_t codec_settings;
+       int look_check;
+       int look_ts;
 };
 
 struct {
@@ -610,6 +612,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
 
        if (*flag & SFF_PLC) {
                switch_core_session_t *session = codec->session;
+               switch_channel_t *channel = switch_core_session_get_channel(session);
                switch_jb_t *jb = NULL;
                int got_frame = 0;
 
@@ -618,20 +621,40 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
                encoded_data = NULL;
 
                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 && 
-                               codec->cur_frame && (jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO))) {
+                       if (!context->look_check) {
+                               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 };
                                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.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_len = frame.datalen;
+
+                                       if ((fec = switch_opus_has_fec(frame.data, frame.datalen))) {
+                                               got_frame = 1;
+                                       }
+                                       
                                        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", 
                                                                                  codec->cur_frame->seq, encoded_data_len);
                                                } else {
@@ -639,7 +662,7 @@ static switch_status_t switch_opus_decode(switch_codec_t *codec,
                                                                                  codec->cur_frame->seq, encoded_data_len );
                                                }
                                        }
-                               } 
+                               }
                        }
                }
                
@@ -784,6 +807,13 @@ static switch_status_t opus_load_config(switch_bool_t reload)
                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"))) {
                for (param = switch_xml_child(settings, "param"); param; param = param->next) {
                        char *key = (char *) switch_xml_attr_soft(param, "name");
index cf6bf6dd69697d9694759b76e04b58b1e38b4843..f799b11fdb1dc800f6b6f7520d41d6509704fe5f 100644 (file)
@@ -65,6 +65,7 @@ struct switch_jb_s {
        uint32_t target_ts;
        uint32_t last_target_ts;
        uint16_t psuedo_seq;
+       uint16_t last_psuedo_seq;
        uint32_t visible_nodes;
        uint32_t complete_frames;
        uint32_t frame_len;
@@ -581,6 +582,8 @@ static inline void increment_ts(switch_jb_t *jb)
 {
        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->psuedo_seq++;
 }
@@ -589,6 +592,7 @@ static inline void set_read_ts(switch_jb_t *jb, uint32_t ts)
 {
        if (!ts) return;
 
+       jb->last_psuedo_seq = jb->psuedo_seq;
        jb->last_target_ts = ts;
        jb->target_ts = htonl((ntohl(jb->last_target_ts) + jb->samples_per_frame));
        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)
 {
+       jb->last_target_seq = jb->target_seq;
        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_jb_node_t *node = NULL;
-
        if (seq) {
                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) {
                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) {
@@ -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->m = node->packet.header.m;
                frame->datalen = node->len;
+
                if (frame->data && frame->buflen > 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_status_t status;
-       
+       int plc = 0;
+
        switch_mutex_lock(jb->mutex);
 
        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);
                                } else {
                                        jb_debug(jb, 2, "%s", "Frame not found suggest PLC\n");
+                                       plc = 1;
                                        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:
 
+       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);
 
        if (status == SWITCH_STATUS_SUCCESS && jb->type == SJB_AUDIO) {
index 7573aa16c6173329201fc28a8455457c460ce21b..62e48e7d1cbba327565eea3dce4ebab7bcddeb80 100644 (file)
@@ -4059,7 +4059,9 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *
        } else {
                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_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);
        }
 
@@ -5459,8 +5461,8 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t
                                {
                                        (*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);
+                                       rtp_session->last_rtp_hdr = rtp_session->recv_msg.header;
                                }
                                break;
                        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) {
                        switch_set_flag(frame, SFF_RFC2833);
                }
-               frame->timestamp = ntohl(rtp_session->recv_msg.header.ts);
-               frame->seq = (uint16_t) ntohs((uint16_t) rtp_session->recv_msg.header.seq);
+               frame->timestamp = ntohl(rtp_session->last_rtp_hdr.ts);
+               frame->seq = (uint16_t) ntohs((uint16_t) rtp_session->last_rtp_hdr.seq);
                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