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 "rtp.h"
|
||||||
#include "codec.h"
|
#include "codec.h"
|
||||||
|
|
||||||
const uint16_t min_jbuf_size = 4;
|
JitterBuffer *create_queue(unsigned int capacity)
|
||||||
const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */
|
|
||||||
|
|
||||||
int empty_queue(JitterBuffer *q)
|
|
||||||
{
|
{
|
||||||
while (q->size > 0) {
|
unsigned int size = 1;
|
||||||
rtp_free_msg(NULL, q->queue[q->front]);
|
|
||||||
q->front++;
|
|
||||||
|
|
||||||
if (q->front == q->capacity)
|
while (size <= (capacity + 1) * 2) {
|
||||||
q->front = 0;
|
size *= 2;
|
||||||
|
|
||||||
q->size--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q->id_set = 0;
|
|
||||||
q->queue_ready = 0;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
JitterBuffer *create_queue(int capacity)
|
|
||||||
{
|
|
||||||
JitterBuffer *q;
|
JitterBuffer *q;
|
||||||
|
|
||||||
if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL;
|
if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL;
|
||||||
|
|
||||||
if (!(q->queue = calloc(sizeof(RTPMessage *), capacity))) {
|
if (!(q->queue = calloc(sizeof(RTPMessage *), size))) {
|
||||||
free(q);
|
free(q);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
q->size = 0;
|
q->size = size;
|
||||||
q->capacity = capacity >= min_jbuf_size ? capacity : min_jbuf_size;
|
q->capacity = capacity;
|
||||||
q->front = 0;
|
|
||||||
q->rear = -1;
|
|
||||||
q->queue_ready = 0;
|
|
||||||
q->current_id = 0;
|
|
||||||
q->current_ts = 0;
|
|
||||||
q->id_set = 0;
|
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -82,106 +62,59 @@ void terminate_queue(JitterBuffer *q)
|
|||||||
{
|
{
|
||||||
if (!q) return;
|
if (!q) return;
|
||||||
|
|
||||||
empty_queue(q);
|
for (; q->bottom != q->top; ++q->bottom) {
|
||||||
free(q->queue);
|
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);
|
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 */
|
/* 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)
|
RTPMessage *dequeue(JitterBuffer *q, int *success)
|
||||||
{
|
{
|
||||||
if (q->size == 0 || q->queue_ready == 0) { /* Empty queue */
|
if (q->top == q->bottom) {
|
||||||
q->queue_ready = 0;
|
|
||||||
*success = 0;
|
*success = 0;
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int front = q->front;
|
unsigned int num = q->bottom % q->size;
|
||||||
|
|
||||||
if (q->id_set == 0) {
|
if (q->queue[num]) {
|
||||||
q->current_id = q->queue[front]->header->sequnum;
|
RTPMessage *ret = q->queue[num];
|
||||||
q->current_ts = q->queue[front]->header->timestamp;
|
q->queue[num] = NULL;
|
||||||
q->id_set = 1;
|
++q->bottom;
|
||||||
} else {
|
*success = 1;
|
||||||
int next_id = q->queue[front]->header->sequnum;
|
return ret;
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
q->size--;
|
if (q->top - q->bottom > q->capacity) {
|
||||||
q->front++;
|
++q->bottom;
|
||||||
|
*success = 2;
|
||||||
if (q->front == q->capacity)
|
return NULL;
|
||||||
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->size >= min_readiness_idx) q->queue_ready = 1;
|
*success = 0;
|
||||||
|
return NULL;
|
||||||
++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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -78,17 +78,13 @@ typedef struct _CodecState {
|
|||||||
|
|
||||||
typedef struct _JitterBuffer {
|
typedef struct _JitterBuffer {
|
||||||
RTPMessage **queue;
|
RTPMessage **queue;
|
||||||
uint16_t capacity;
|
unsigned int size;
|
||||||
uint16_t size;
|
unsigned int capacity;
|
||||||
uint16_t front;
|
uint16_t bottom;
|
||||||
uint16_t rear;
|
uint16_t top;
|
||||||
uint8_t queue_ready;
|
|
||||||
uint16_t current_id;
|
|
||||||
uint32_t current_ts;
|
|
||||||
uint8_t id_set;
|
|
||||||
} JitterBuffer;
|
} JitterBuffer;
|
||||||
|
|
||||||
JitterBuffer *create_queue(int capacity);
|
JitterBuffer *create_queue(unsigned int capacity);
|
||||||
void terminate_queue(JitterBuffer *q);
|
void terminate_queue(JitterBuffer *q);
|
||||||
void queue(JitterBuffer *q, RTPMessage *pk);
|
void queue(JitterBuffer *q, RTPMessage *pk);
|
||||||
RTPMessage *dequeue(JitterBuffer *q, int *success);
|
RTPMessage *dequeue(JitterBuffer *q, int *success);
|
||||||
|
@ -95,7 +95,7 @@ const ToxAvCodecSettings av_DefaultSettings = {
|
|||||||
1,
|
1,
|
||||||
600,
|
600,
|
||||||
|
|
||||||
6
|
1
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user