mirror of
https://github.com/irungentoo/toxcore.git
synced 2024-03-22 13:30:51 +08:00
Rewrote audio packet queue.
Audio killing itself after 20 minutes in a call should be fixed.
This commit is contained in:
parent
f6d829d8f0
commit
443abcfafe
153
toxav/codec.c
153
toxav/codec.c
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -95,7 +95,7 @@ const ToxAvCodecSettings av_DefaultSettings = {
|
|||
1,
|
||||
600,
|
||||
|
||||
6
|
||||
1
|
||||
};
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user