FS-4781 --resolve I added some more code to the jb for seq but I still think the timestamp is more reliable than the seq since we can't know if the rtp is passing over a media proxy who may preserve the timestamps but still rewrite the seq, its more likely the ts shows the more accurate order of the rtp stream

This commit is contained in:
Anthony Minessale 2012-11-01 09:00:38 -05:00
parent 254514448f
commit 2494448846
4 changed files with 73 additions and 10 deletions

View File

@ -69,6 +69,7 @@ struct stfu_instance {
struct stfu_queue *old_queue;
struct stfu_frame *last_frame;
uint32_t cur_ts;
uint16_t cur_seq;
uint32_t last_wr_ts;
uint32_t last_rd_ts;
uint32_t samples_per_packet;
@ -361,6 +362,7 @@ void stfu_n_reset(stfu_instance_t *i)
stfu_n_sync(i, 1);
i->cur_ts = 0;
i->cur_seq = 0;
i->last_wr_ts = 0;
i->last_rd_ts = 0;
i->miss_count = 0;
@ -650,6 +652,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
for (x = 0; x < i->out_queue->array_len; x++) {
if (!i->out_queue->array[x].was_read) {
i->cur_ts = i->out_queue->array[x].ts;
i->cur_ts = i->out_queue->array[x].seq;
break;
}
if (i->cur_ts == 0) {
@ -661,6 +664,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
}
} else {
i->cur_ts = i->cur_ts + i->samples_per_packet;
i->cur_seq++;
}
found = stfu_n_find_frame(i, i->out_queue, i->last_wr_ts, i->cur_ts, &rframe);
@ -679,12 +683,14 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
if (found) {
i->cur_ts = rframe->ts;
i->cur_seq = rframe->seq;
}
if (i->sync_out) {
if (!found) {
if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
i->cur_ts = rframe->ts;
i->cur_seq = rframe->seq;
}
if (stfu_log != null_logger && i->debug) {
@ -783,6 +789,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
rframe->dlen = i->plc_len;
rframe->pt = i->plc_pt;
rframe->ts = i->cur_ts;
rframe->seq = i->cur_seq;
i->miss_count++;
if (stfu_log != null_logger && i->debug) {
@ -799,6 +806,38 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
return rframe;
}
int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame)
{
uint32_t i = 0, j = 0;
stfu_queue_t *queues[] = { jb->out_queue, jb->in_queue, jb->old_queue};
stfu_queue_t *queue = NULL;
stfu_frame_t *frame = NULL;
uint32_t target_ts = 0;
if (!next_frame) return 0;
target_ts = timestamp + (distance - 1) * jb->samples_per_packet;
for (i = 0; i < sizeof(queues)/sizeof(queues[0]); i++) {
queue = queues[i];
if (!queue) continue;
for(j = 0; j < queue->array_size; j++) {
frame = &queue->array[j];
/* FIXME: ts rollover happened? bad luck */
if (frame->ts > target_ts) {
memcpy(next_frame, frame, sizeof(stfu_frame_t));
return 1;
}
}
}
return 0;
}
#ifdef WIN32
#ifndef vsnprintf
#define vsnprintf _vsnprintf
@ -927,7 +966,6 @@ static void default_logger(const char *file, const char *func, int line, int lev
}
/* For Emacs:
* Local Variables:
* mode:c

View File

@ -191,6 +191,7 @@ stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_qlen, uint32_t samples_
stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen);
stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint16_t seq, uint32_t pt, void *data, size_t datalen, uint32_t timer_ts, int last);
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);
int32_t stfu_n_copy_next_frame(stfu_instance_t *jb, uint32_t timestamp, uint16_t seq, uint16_t distance, stfu_frame_t *next_frame);
void stfu_n_reset(stfu_instance_t *i);
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);

View File

@ -4,6 +4,7 @@ SILK_BUILDDIR=$(switch_builddir)/libs/silk
LOCAL_CFLAGS=-I$(SILK_DIR)/src -I$(SILK_DIR)/interface
SILK_LA=$(SILK_BUILDDIR)/.libs/libSKP_SILK_SDK.la
LOCAL_LIBADD=$(SILK_LA)
LOCAL_OBJS=$(BASE)/libs/stfu/stfu.o
include $(BASE)/build/modmake.rules
$(SILK_LA): $(SILK_DIR)/.update

View File

@ -31,6 +31,7 @@
*/
#include "switch.h"
#include "stfu.h"
#include "SKP_Silk_SDK_API.h"
SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load);
@ -321,23 +322,43 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec,
SKP_int16 ret, len;
int16_t *target = decoded_data;
switch_core_session_t *session = codec->session;
stfu_instance_t *jb;
stfu_instance_t *jb = NULL;
SKP_int lost_flag = (*flag & SFF_PLC);
stfu_frame_t next_frame;
SKP_uint8 recbuff[STFU_DATALEN];
SKP_int16 reclen;
int32_t found_frame;
switch_bool_t did_lbrr = SWITCH_FALSE;
*decoded_data_len = 0;
if (session) {
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
}
if (jb) {
/* to allow compile */
jb = NULL;
if (lost_flag) {
if (session) {
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
}
if (jb && codec && codec->cur_frame) {
for (int i = 1; i <= MAX_LBRR_DELAY; i++) {
found_frame = stfu_n_copy_next_frame(jb, codec->cur_frame->timestamp, codec->cur_frame->seq, i, &next_frame);
if (found_frame) {
SKP_Silk_SDK_search_for_LBRR(next_frame.data, next_frame.dlen, i, (SKP_uint8*) &recbuff, &reclen);
if (reclen) {
encoded_data = &recbuff;
encoded_data_len = reclen;
lost_flag = SKP_FALSE;
did_lbrr = SWITCH_TRUE;
break;
}
}
}
}
}
do {
ret = SKP_Silk_SDK_Decode(context->dec_state,
&context->decoder_object,
((*flag & SFF_PLC)),
lost_flag,
encoded_data,
encoded_data_len,
target,
@ -345,6 +366,8 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec,
if (ret){
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SKP_Silk_Decode returned %d!\n", ret);
printSilkError(ret);
/* if FEC was activated, we can ignore bit errors*/
if (! (ret == SKP_SILK_DEC_PAYLOAD_ERROR && did_lbrr))
return SWITCH_STATUS_FALSE;
}