Rewrote audio packet queue.

Audio killing itself after 20 minutes in a call should be fixed.
This commit is contained in:
irungentoo 2014-07-24 19:45:38 -04:00
parent f6d829d8f0
commit 443abcfafe
No known key found for this signature in database
GPG Key ID: 10349DC9BED89E98
3 changed files with 49 additions and 120 deletions

View File

@ -36,45 +36,25 @@
#include "rtp.h"
#include "codec.h"
const uint16_t min_jbuf_size = 4;
const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */
int empty_queue(JitterBuffer *q)
JitterBuffer *create_queue(unsigned int capacity)
{
while (q->size > 0) {
rtp_free_msg(NULL, q->queue[q->front]);
q->front++;
unsigned int size = 1;
if (q->front == q->capacity)
q->front = 0;
q->size--;
while (size <= (capacity + 1) * 2) {
size *= 2;
}
q->id_set = 0;
q->queue_ready = 0;
return 0;
}
JitterBuffer *create_queue(int capacity)
{
JitterBuffer *q;
if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL;
if (!(q->queue = calloc(sizeof(RTPMessage *), capacity))) {
if (!(q->queue = calloc(sizeof(RTPMessage *), size))) {
free(q);
return NULL;
}
q->size = 0;
q->capacity = capacity >= min_jbuf_size ? capacity : min_jbuf_size;
q->front = 0;
q->rear = -1;
q->queue_ready = 0;
q->current_id = 0;
q->current_ts = 0;
q->id_set = 0;
q->size = size;
q->capacity = capacity;
return q;
}
@ -82,106 +62,59 @@ void terminate_queue(JitterBuffer *q)
{
if (!q) return;
empty_queue(q);
free(q->queue);
for (; q->bottom != q->top; ++q->bottom) {
if (!q->queue[q->bottom % q->size])
rtp_free_msg(NULL, q->queue[q->bottom % q->size]);
}
LOGGER_DEBUG("Terminated jitter buffer: %p", q);
free(q->queue);
free(q);
}
#define sequnum_older(sn_a, sn_b, ts_a, ts_b) (sn_a > sn_b || ts_a > ts_b)
void queue(JitterBuffer *q, RTPMessage *pk)
{
uint16_t sequnum = pk->header->sequnum;
if (sequnum - q->bottom > q->size)
return;
unsigned int num = sequnum % q->size;
if (q->queue[num])
return;
q->queue[num] = pk;
if ((sequnum - q->bottom) >= (q->top - q->bottom))
q->top = sequnum + 1;
}
/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
RTPMessage *dequeue(JitterBuffer *q, int *success)
{
if (q->size == 0 || q->queue_ready == 0) { /* Empty queue */
q->queue_ready = 0;
if (q->top == q->bottom) {
*success = 0;
return NULL;
}
int front = q->front;
unsigned int num = q->bottom % q->size;
if (q->id_set == 0) {
q->current_id = q->queue[front]->header->sequnum;
q->current_ts = q->queue[front]->header->timestamp;
q->id_set = 1;
} else {
int next_id = q->queue[front]->header->sequnum;
int next_ts = q->queue[front]->header->timestamp;
/* if this packet is indeed the expected packet */
if (next_id == (q->current_id + 1) % MAX_SEQU_NUM) {
q->current_id = next_id;
q->current_ts = next_ts;
} else {
if (sequnum_older(next_id, q->current_id, next_ts, q->current_ts)) {
LOGGER_DEBUG("nextid: %d current: %d\n", next_id, q->current_id);
q->current_id = (q->current_id + 1) % MAX_SEQU_NUM;
*success = 2; /* tell the decoder the packet is lost */
return NULL;
} else {
LOGGER_DEBUG("Packet too old");
*success = 0;
return NULL;
}
}
if (q->queue[num]) {
RTPMessage *ret = q->queue[num];
q->queue[num] = NULL;
++q->bottom;
*success = 1;
return ret;
}
q->size--;
q->front++;
if (q->front == q->capacity)
q->front = 0;
*success = 1;
q->current_id = q->queue[front]->header->sequnum;
q->current_ts = q->queue[front]->header->timestamp;
return q->queue[front];
}
void queue(JitterBuffer *q, RTPMessage *pk)
{
if (q->size == q->capacity) { /* Full, empty queue */
LOGGER_DEBUG("Queue full s(%d) c(%d), emptying...", q->size, q->capacity);
empty_queue(q);
if (q->top - q->bottom > q->capacity) {
++q->bottom;
*success = 2;
return NULL;
}
if (q->size >= min_readiness_idx) q->queue_ready = 1;
++q->size;
++q->rear;
if (q->rear == q->capacity) q->rear = 0;
q->queue[q->rear] = pk;
int a;
int j;
a = q->rear;
for (j = 0; j < q->size - 1; ++j) {
int b = a - 1;
if (b < 0)
b += q->capacity;
if (sequnum_older(q->queue[b]->header->sequnum, q->queue[a]->header->sequnum,
q->queue[b]->header->timestamp, q->queue[a]->header->timestamp)) {
RTPMessage *temp;
temp = q->queue[a];
q->queue[a] = q->queue[b];
q->queue[b] = temp;
LOGGER_DEBUG("Had to swap");
} else {
break;
}
a -= 1;
if (a < 0) a += q->capacity;
}
*success = 0;
return NULL;
}

View File

@ -78,17 +78,13 @@ typedef struct _CodecState {
typedef struct _JitterBuffer {
RTPMessage **queue;
uint16_t capacity;
uint16_t size;
uint16_t front;
uint16_t rear;
uint8_t queue_ready;
uint16_t current_id;
uint32_t current_ts;
uint8_t id_set;
unsigned int size;
unsigned int capacity;
uint16_t bottom;
uint16_t top;
} JitterBuffer;
JitterBuffer *create_queue(int capacity);
JitterBuffer *create_queue(unsigned int capacity);
void terminate_queue(JitterBuffer *q);
void queue(JitterBuffer *q, RTPMessage *pk);
RTPMessage *dequeue(JitterBuffer *q, int *success);

View File

@ -95,7 +95,7 @@ const ToxAvCodecSettings av_DefaultSettings = {
1,
600,
6
1
};