summaryrefslogtreecommitdiff
path: root/toxav
diff options
context:
space:
mode:
authorirungentoo <irungentoo@gmail.com>2014-07-24 19:45:38 -0400
committerirungentoo <irungentoo@gmail.com>2014-07-24 19:45:38 -0400
commit443abcfafe7c194555f29ff4c297228d486a184e (patch)
treebd725ef94a6c76bdcdddf4bea95ca3e16b8c2057 /toxav
parentf6d829d8f08b83878437da8170ef340dfa781d89 (diff)
Rewrote audio packet queue.
Audio killing itself after 20 minutes in a call should be fixed.
Diffstat (limited to 'toxav')
-rw-r--r--toxav/codec.c151
-rw-r--r--toxav/codec.h14
-rw-r--r--toxav/toxav.c2
3 files changed, 48 insertions, 119 deletions
diff --git a/toxav/codec.c b/toxav/codec.c
index b7ca2784..8b1855a0 100644
--- a/toxav/codec.c
+++ b/toxav/codec.c
@@ -36,45 +36,25 @@
36#include "rtp.h" 36#include "rtp.h"
37#include "codec.h" 37#include "codec.h"
38 38
39const uint16_t min_jbuf_size = 4; 39JitterBuffer *create_queue(unsigned int capacity)
40const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */
41
42int empty_queue(JitterBuffer *q)
43{ 40{
44 while (q->size > 0) { 41 unsigned int size = 1;
45 rtp_free_msg(NULL, q->queue[q->front]);
46 q->front++;
47
48 if (q->front == q->capacity)
49 q->front = 0;
50 42
51 q->size--; 43 while (size <= (capacity + 1) * 2) {
44 size *= 2;
52 } 45 }
53 46
54 q->id_set = 0;
55 q->queue_ready = 0;
56 return 0;
57}
58
59JitterBuffer *create_queue(int capacity)
60{
61 JitterBuffer *q; 47 JitterBuffer *q;
62 48
63 if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL; 49 if ( !(q = calloc(sizeof(JitterBuffer), 1)) ) return NULL;
64 50
65 if (!(q->queue = calloc(sizeof(RTPMessage *), capacity))) { 51 if (!(q->queue = calloc(sizeof(RTPMessage *), size))) {
66 free(q); 52 free(q);
67 return NULL; 53 return NULL;
68 } 54 }
69 55
70 q->size = 0; 56 q->size = size;
71 q->capacity = capacity >= min_jbuf_size ? capacity : min_jbuf_size; 57 q->capacity = capacity;
72 q->front = 0;
73 q->rear = -1;
74 q->queue_ready = 0;
75 q->current_id = 0;
76 q->current_ts = 0;
77 q->id_set = 0;
78 return q; 58 return q;
79} 59}
80 60
@@ -82,106 +62,59 @@ void terminate_queue(JitterBuffer *q)
82{ 62{
83 if (!q) return; 63 if (!q) return;
84 64
85 empty_queue(q); 65 for (; q->bottom != q->top; ++q->bottom) {
86 free(q->queue); 66 if (!q->queue[q->bottom % q->size])
67 rtp_free_msg(NULL, q->queue[q->bottom % q->size]);
68 }
87 69
88 LOGGER_DEBUG("Terminated jitter buffer: %p", q); 70 free(q->queue);
89 free(q); 71 free(q);
90} 72}
91 73
92#define sequnum_older(sn_a, sn_b, ts_a, ts_b) (sn_a > sn_b || ts_a > ts_b) 74void queue(JitterBuffer *q, RTPMessage *pk)
93
94/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
95RTPMessage *dequeue(JitterBuffer *q, int *success)
96{ 75{
97 if (q->size == 0 || q->queue_ready == 0) { /* Empty queue */ 76 uint16_t sequnum = pk->header->sequnum;
98 q->queue_ready = 0;
99 *success = 0;
100 return NULL;
101 }
102 77
103 int front = q->front; 78 if (sequnum - q->bottom > q->size)
79 return;
104 80
105 if (q->id_set == 0) { 81 unsigned int num = sequnum % q->size;
106 q->current_id = q->queue[front]->header->sequnum;
107 q->current_ts = q->queue[front]->header->timestamp;
108 q->id_set = 1;
109 } else {
110 int next_id = q->queue[front]->header->sequnum;
111 int next_ts = q->queue[front]->header->timestamp;
112
113 /* if this packet is indeed the expected packet */
114 if (next_id == (q->current_id + 1) % MAX_SEQU_NUM) {
115 q->current_id = next_id;
116 q->current_ts = next_ts;
117 } else {
118 if (sequnum_older(next_id, q->current_id, next_ts, q->current_ts)) {
119 LOGGER_DEBUG("nextid: %d current: %d\n", next_id, q->current_id);
120 q->current_id = (q->current_id + 1) % MAX_SEQU_NUM;
121 *success = 2; /* tell the decoder the packet is lost */
122 return NULL;
123 } else {
124 LOGGER_DEBUG("Packet too old");
125 *success = 0;
126 return NULL;
127 }
128 }
129 }
130 82
131 q->size--; 83 if (q->queue[num])
132 q->front++; 84 return;
133 85
134 if (q->front == q->capacity) 86 q->queue[num] = pk;
135 q->front = 0;
136 87
137 *success = 1; 88 if ((sequnum - q->bottom) >= (q->top - q->bottom))
138 q->current_id = q->queue[front]->header->sequnum; 89 q->top = sequnum + 1;
139 q->current_ts = q->queue[front]->header->timestamp;
140 return q->queue[front];
141} 90}
142 91
143 92/* success is 0 when there is nothing to dequeue, 1 when there's a good packet, 2 when there's a lost packet */
144void queue(JitterBuffer *q, RTPMessage *pk) 93RTPMessage *dequeue(JitterBuffer *q, int *success)
145{ 94{
146 if (q->size == q->capacity) { /* Full, empty queue */ 95 if (q->top == q->bottom) {
147 LOGGER_DEBUG("Queue full s(%d) c(%d), emptying...", q->size, q->capacity); 96 *success = 0;
148 empty_queue(q); 97 return NULL;
149 } 98 }
150 99
151 if (q->size >= min_readiness_idx) q->queue_ready = 1; 100 unsigned int num = q->bottom % q->size;
152
153 ++q->size;
154 ++q->rear;
155
156 if (q->rear == q->capacity) q->rear = 0;
157 101
158 q->queue[q->rear] = pk; 102 if (q->queue[num]) {
159 103 RTPMessage *ret = q->queue[num];
160 int a; 104 q->queue[num] = NULL;
161 int j; 105 ++q->bottom;
162 a = q->rear; 106 *success = 1;
163 107 return ret;
164 for (j = 0; j < q->size - 1; ++j) { 108 }
165 int b = a - 1;
166
167 if (b < 0)
168 b += q->capacity;
169
170 if (sequnum_older(q->queue[b]->header->sequnum, q->queue[a]->header->sequnum,
171 q->queue[b]->header->timestamp, q->queue[a]->header->timestamp)) {
172 RTPMessage *temp;
173 temp = q->queue[a];
174 q->queue[a] = q->queue[b];
175 q->queue[b] = temp;
176 LOGGER_DEBUG("Had to swap");
177 } else {
178 break;
179 }
180
181 a -= 1;
182 109
183 if (a < 0) a += q->capacity; 110 if (q->top - q->bottom > q->capacity) {
111 ++q->bottom;
112 *success = 2;
113 return NULL;
184 } 114 }
115
116 *success = 0;
117 return NULL;
185} 118}
186 119
187 120
diff --git a/toxav/codec.h b/toxav/codec.h
index a464ec8f..755673f3 100644
--- a/toxav/codec.h
+++ b/toxav/codec.h
@@ -78,17 +78,13 @@ typedef struct _CodecState {
78 78
79typedef struct _JitterBuffer { 79typedef struct _JitterBuffer {
80 RTPMessage **queue; 80 RTPMessage **queue;
81 uint16_t capacity; 81 unsigned int size;
82 uint16_t size; 82 unsigned int capacity;
83 uint16_t front; 83 uint16_t bottom;
84 uint16_t rear; 84 uint16_t top;
85 uint8_t queue_ready;
86 uint16_t current_id;
87 uint32_t current_ts;
88 uint8_t id_set;
89} JitterBuffer; 85} JitterBuffer;
90 86
91JitterBuffer *create_queue(int capacity); 87JitterBuffer *create_queue(unsigned int capacity);
92void terminate_queue(JitterBuffer *q); 88void terminate_queue(JitterBuffer *q);
93void queue(JitterBuffer *q, RTPMessage *pk); 89void queue(JitterBuffer *q, RTPMessage *pk);
94RTPMessage *dequeue(JitterBuffer *q, int *success); 90RTPMessage *dequeue(JitterBuffer *q, int *success);
diff --git a/toxav/toxav.c b/toxav/toxav.c
index dfb5dce3..7e93099e 100644
--- a/toxav/toxav.c
+++ b/toxav/toxav.c
@@ -95,7 +95,7 @@ const ToxAvCodecSettings av_DefaultSettings = {
95 1, 95 1,
96 600, 96 600,
97 97
98 6 98 1
99}; 99};
100 100
101 101