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:
parent
254514448f
commit
2494448846
|
@ -69,6 +69,7 @@ struct stfu_instance {
|
||||||
struct stfu_queue *old_queue;
|
struct stfu_queue *old_queue;
|
||||||
struct stfu_frame *last_frame;
|
struct stfu_frame *last_frame;
|
||||||
uint32_t cur_ts;
|
uint32_t cur_ts;
|
||||||
|
uint16_t cur_seq;
|
||||||
uint32_t last_wr_ts;
|
uint32_t last_wr_ts;
|
||||||
uint32_t last_rd_ts;
|
uint32_t last_rd_ts;
|
||||||
uint32_t samples_per_packet;
|
uint32_t samples_per_packet;
|
||||||
|
@ -361,6 +362,7 @@ void stfu_n_reset(stfu_instance_t *i)
|
||||||
stfu_n_sync(i, 1);
|
stfu_n_sync(i, 1);
|
||||||
|
|
||||||
i->cur_ts = 0;
|
i->cur_ts = 0;
|
||||||
|
i->cur_seq = 0;
|
||||||
i->last_wr_ts = 0;
|
i->last_wr_ts = 0;
|
||||||
i->last_rd_ts = 0;
|
i->last_rd_ts = 0;
|
||||||
i->miss_count = 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++) {
|
for (x = 0; x < i->out_queue->array_len; x++) {
|
||||||
if (!i->out_queue->array[x].was_read) {
|
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].ts;
|
||||||
|
i->cur_ts = i->out_queue->array[x].seq;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (i->cur_ts == 0) {
|
if (i->cur_ts == 0) {
|
||||||
|
@ -661,6 +664,7 @@ stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
i->cur_ts = i->cur_ts + i->samples_per_packet;
|
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);
|
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) {
|
if (found) {
|
||||||
i->cur_ts = rframe->ts;
|
i->cur_ts = rframe->ts;
|
||||||
|
i->cur_seq = rframe->seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i->sync_out) {
|
if (i->sync_out) {
|
||||||
if (!found) {
|
if (!found) {
|
||||||
if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
|
if ((found = stfu_n_find_any_frame(i, i->out_queue, &rframe))) {
|
||||||
i->cur_ts = rframe->ts;
|
i->cur_ts = rframe->ts;
|
||||||
|
i->cur_seq = rframe->seq;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (stfu_log != null_logger && i->debug) {
|
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->dlen = i->plc_len;
|
||||||
rframe->pt = i->plc_pt;
|
rframe->pt = i->plc_pt;
|
||||||
rframe->ts = i->cur_ts;
|
rframe->ts = i->cur_ts;
|
||||||
|
rframe->seq = i->cur_seq;
|
||||||
i->miss_count++;
|
i->miss_count++;
|
||||||
|
|
||||||
if (stfu_log != null_logger && i->debug) {
|
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;
|
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
|
#ifdef WIN32
|
||||||
#ifndef vsnprintf
|
#ifndef vsnprintf
|
||||||
#define vsnprintf _vsnprintf
|
#define vsnprintf _vsnprintf
|
||||||
|
@ -927,7 +966,6 @@ static void default_logger(const char *file, const char *func, int line, int lev
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* For Emacs:
|
/* For Emacs:
|
||||||
* Local Variables:
|
* Local Variables:
|
||||||
* mode:c
|
* mode:c
|
||||||
|
|
|
@ -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_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_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);
|
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);
|
void stfu_n_reset(stfu_instance_t *i);
|
||||||
stfu_status_t stfu_n_sync(stfu_instance_t *i, uint32_t packets);
|
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);
|
void stfu_n_call_me(stfu_instance_t *i, stfu_n_call_me_t callback, void *udata);
|
||||||
|
|
|
@ -4,6 +4,7 @@ SILK_BUILDDIR=$(switch_builddir)/libs/silk
|
||||||
LOCAL_CFLAGS=-I$(SILK_DIR)/src -I$(SILK_DIR)/interface
|
LOCAL_CFLAGS=-I$(SILK_DIR)/src -I$(SILK_DIR)/interface
|
||||||
SILK_LA=$(SILK_BUILDDIR)/.libs/libSKP_SILK_SDK.la
|
SILK_LA=$(SILK_BUILDDIR)/.libs/libSKP_SILK_SDK.la
|
||||||
LOCAL_LIBADD=$(SILK_LA)
|
LOCAL_LIBADD=$(SILK_LA)
|
||||||
|
LOCAL_OBJS=$(BASE)/libs/stfu/stfu.o
|
||||||
include $(BASE)/build/modmake.rules
|
include $(BASE)/build/modmake.rules
|
||||||
|
|
||||||
$(SILK_LA): $(SILK_DIR)/.update
|
$(SILK_LA): $(SILK_DIR)/.update
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "switch.h"
|
#include "switch.h"
|
||||||
|
#include "stfu.h"
|
||||||
#include "SKP_Silk_SDK_API.h"
|
#include "SKP_Silk_SDK_API.h"
|
||||||
|
|
||||||
SWITCH_MODULE_LOAD_FUNCTION(mod_silk_load);
|
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;
|
SKP_int16 ret, len;
|
||||||
int16_t *target = decoded_data;
|
int16_t *target = decoded_data;
|
||||||
switch_core_session_t *session = codec->session;
|
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;
|
*decoded_data_len = 0;
|
||||||
|
|
||||||
if (session) {
|
if (lost_flag) {
|
||||||
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
if (session) {
|
||||||
}
|
jb = switch_core_session_get_jb(session, SWITCH_MEDIA_TYPE_AUDIO);
|
||||||
|
}
|
||||||
if (jb) {
|
if (jb && codec && codec->cur_frame) {
|
||||||
/* to allow compile */
|
for (int i = 1; i <= MAX_LBRR_DELAY; i++) {
|
||||||
jb = NULL;
|
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 {
|
do {
|
||||||
ret = SKP_Silk_SDK_Decode(context->dec_state,
|
ret = SKP_Silk_SDK_Decode(context->dec_state,
|
||||||
&context->decoder_object,
|
&context->decoder_object,
|
||||||
((*flag & SFF_PLC)),
|
lost_flag,
|
||||||
encoded_data,
|
encoded_data,
|
||||||
encoded_data_len,
|
encoded_data_len,
|
||||||
target,
|
target,
|
||||||
|
@ -345,6 +366,8 @@ static switch_status_t switch_silk_decode(switch_codec_t *codec,
|
||||||
if (ret){
|
if (ret){
|
||||||
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SKP_Silk_Decode returned %d!\n", ret);
|
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "SKP_Silk_Decode returned %d!\n", ret);
|
||||||
printSilkError(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;
|
return SWITCH_STATUS_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue