refactor STFU a bit

This commit is contained in:
Anthony Minessale 2010-11-09 11:49:07 -06:00
parent dd4fb5bee5
commit 794db40e52
4 changed files with 70 additions and 78 deletions

View File

@ -38,7 +38,6 @@ struct stfu_queue {
uint32_t array_size;
uint32_t array_len;
uint32_t wr_len;
uint32_t last_index;
};
typedef struct stfu_queue stfu_queue_t;
@ -47,10 +46,12 @@ struct stfu_instance {
struct stfu_queue b_queue;
struct stfu_queue *in_queue;
struct stfu_queue *out_queue;
uint32_t last_ts;
struct stfu_frame *last_frame;
uint32_t last_wr_ts;
uint32_t last_rd_ts;
uint32_t interval;
uint32_t miss_count;
uint8_t running;
uint32_t max_plc;
};
@ -112,7 +113,7 @@ stfu_status_t stfu_n_resize(stfu_instance_t *i, uint32_t qlen)
return s;
}
stfu_instance_t *stfu_n_init(uint32_t qlen)
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc)
{
struct stfu_instance *i;
@ -125,6 +126,13 @@ stfu_instance_t *stfu_n_init(uint32_t qlen)
stfu_n_init_aqueue(&i->b_queue, qlen);
i->in_queue = &i->a_queue;
i->out_queue = &i->b_queue;
if (max_plc) {
i->max_plc = max_plc;
} else {
i->max_plc = qlen / 2;
}
return i;
}
@ -135,10 +143,9 @@ void stfu_n_reset(stfu_instance_t *i)
i->in_queue->array_len = 0;
i->out_queue->array_len = 0;
i->out_queue->wr_len = 0;
i->out_queue->last_index = 0;
i->last_frame = NULL;
i->miss_count = 0;
i->last_ts = 0;
i->running = 0;
i->last_wr_ts = 0;
i->miss_count = 0;
i->interval = 0;
}
@ -197,7 +204,7 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
i->in_queue->array_len = 0;
i->out_queue->wr_len = 0;
i->out_queue->last_index = 0;
i->last_frame = NULL;
i->miss_count = 0;
if (stfu_n_process(i, i->out_queue) < 0) {
@ -222,6 +229,8 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
cplen = sizeof(frame->data);
}
i->last_rd_ts = ts;
memcpy(frame->data, data, cplen);
frame->pt = pt;
frame->ts = ts;
@ -231,88 +240,71 @@ stfu_status_t stfu_n_add_data(stfu_instance_t *i, uint32_t ts, uint32_t pt, void
return STFU_IT_WORKED;
}
static int stfu_n_find_frame(stfu_queue_t *queue, uint32_t ts, stfu_frame_t **r_frame, uint32_t *index)
{
uint32_t i = 0;
stfu_frame_t *frame = NULL;
assert(r_frame);
assert(index);
*r_frame = NULL;
for(i = 0; i < queue->array_len; i++) {
frame = &queue->array[i];
if (frame->ts == ts) {
*r_frame = frame;
*index = i;
frame->was_read = 1;
return 1;
}
}
return 0;
}
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i)
{
uint32_t index, index2;
uint32_t index;
uint32_t should_have = 0;
stfu_frame_t *frame = NULL, *rframe = NULL;
stfu_frame_t *rframe = NULL;
if (((i->out_queue->wr_len == i->out_queue->array_len) || !i->out_queue->array_len)) {
return NULL;
}
if (i->running) {
should_have = i->last_ts + i->interval;
if (i->last_wr_ts) {
should_have = i->last_wr_ts + i->interval;
} else {
should_have = i->out_queue->array[0].ts;
}
for(index = 0; index < i->out_queue->array_len; index++) {
if (i->out_queue->array[index].was_read) {
continue;
}
frame = &i->out_queue->array[index];
if (frame->ts != should_have) {
unsigned int tried = 0;
for (index2 = 0; index2 < i->out_queue->array_len; index2++) {
if (i->out_queue->array[index2].was_read) {
continue;
}
tried++;
if (i->out_queue->array[index2].ts == should_have) {
rframe = &i->out_queue->array[index2];
i->out_queue->last_index = index2;
goto done;
}
}
for (index2 = 0; index2 < i->in_queue->array_len; index2++) {
if (i->in_queue->array[index2].was_read) {
continue;
}
tried++;
if (i->in_queue->array[index2].ts == should_have) {
rframe = &i->in_queue->array[index2];
goto done;
}
}
i->miss_count++;
if (i->miss_count > 10 || (i->in_queue->array_len == i->in_queue->array_size) ||
tried >= (i->in_queue->array_size + i->out_queue->array_size)) {
i->running = 0;
i->interval = 0;
i->out_queue->wr_len = i->out_queue->array_size;
return NULL;
}
i->last_ts = should_have;
rframe = &i->out_queue->int_frame;
rframe->dlen = i->out_queue->array[i->out_queue->last_index].dlen;
/* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */
memcpy(rframe->data, i->out_queue->array[i->out_queue->last_index].data, rframe->dlen);
rframe->ts = should_have;
i->out_queue->wr_len++;
i->running = 1;
return rframe;
} else {
rframe = &i->out_queue->array[index];
i->out_queue->last_index = index;
goto done;
}
}
done:
if (rframe) {
if (stfu_n_find_frame(i->out_queue, should_have, &rframe, &index) || stfu_n_find_frame(i->in_queue, should_have, &rframe, &index)) {
i->last_frame = rframe;
i->out_queue->wr_len++;
i->last_ts = rframe->ts;
i->last_wr_ts = rframe->ts;
rframe->was_read = 1;
i->running = 1;
i->miss_count = 0;
}
} else {
i->last_wr_ts = should_have;
rframe = &i->out_queue->int_frame;
if (i->last_frame && i->last_frame != rframe) {
rframe->dlen = i->last_frame->dlen;
/* poor man's plc.. Copy the last frame, but we flag it so you can use a better one if you wish */
memcpy(rframe->data, i->last_frame->data, rframe->dlen);
}
rframe->ts = should_have;
if (++i->miss_count > i->max_plc) {
i->interval = 0;
i->out_queue->wr_len = i->out_queue->array_size;
i->last_wr_ts = 0;
rframe = NULL;
}
}
return rframe;
}

View File

@ -96,7 +96,7 @@ typedef struct {
void stfu_n_report(stfu_instance_t *i, stfu_report_t *r);
void stfu_n_destroy(stfu_instance_t **i);
stfu_instance_t *stfu_n_init(uint32_t qlen);
stfu_instance_t *stfu_n_init(uint32_t qlen, uint32_t max_plc);
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, uint32_t pt, void *data, size_t datalen, int last);
stfu_frame_t *stfu_n_read_a_frame(stfu_instance_t *i);

View File

@ -2190,7 +2190,7 @@ SWITCH_DECLARE(void) switch_ivr_delay_echo(switch_core_session_t *session, uint3
qlen = delay_ms / (interval);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Setting delay to %dms (%d frames)\n", delay_ms, qlen);
jb = stfu_n_init(qlen);
jb = stfu_n_init(qlen, 0);
write_frame.codec = switch_core_session_get_read_codec(session);

View File

@ -1616,7 +1616,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_activate_stun_ping(switch_rtp_t *rtp_
SWITCH_DECLARE(switch_status_t) switch_rtp_activate_jitter_buffer(switch_rtp_t *rtp_session, uint32_t queue_frames)
{
rtp_session->jb = stfu_n_init(queue_frames);
rtp_session->jb = stfu_n_init(queue_frames, 0);
return SWITCH_STATUS_SUCCESS;
}