diff options
author | irungentoo <irungentoo@gmail.com> | 2014-07-24 19:45:38 -0400 |
---|---|---|
committer | irungentoo <irungentoo@gmail.com> | 2014-07-24 19:45:38 -0400 |
commit | 443abcfafe7c194555f29ff4c297228d486a184e (patch) | |
tree | bd725ef94a6c76bdcdddf4bea95ca3e16b8c2057 /toxav | |
parent | f6d829d8f08b83878437da8170ef340dfa781d89 (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.c | 151 | ||||
-rw-r--r-- | toxav/codec.h | 14 | ||||
-rw-r--r-- | toxav/toxav.c | 2 |
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 | ||
39 | const uint16_t min_jbuf_size = 4; | 39 | JitterBuffer *create_queue(unsigned int capacity) |
40 | const uint16_t min_readiness_idx = 2; /* when is buffer ready to dqq */ | ||
41 | |||
42 | int 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 | |||
59 | JitterBuffer *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) | 74 | void 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 */ | ||
95 | RTPMessage *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 */ | |
144 | void queue(JitterBuffer *q, RTPMessage *pk) | 93 | RTPMessage *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 | ||
79 | typedef struct _JitterBuffer { | 79 | typedef 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 | ||
91 | JitterBuffer *create_queue(int capacity); | 87 | JitterBuffer *create_queue(unsigned int capacity); |
92 | void terminate_queue(JitterBuffer *q); | 88 | void terminate_queue(JitterBuffer *q); |
93 | void queue(JitterBuffer *q, RTPMessage *pk); | 89 | void queue(JitterBuffer *q, RTPMessage *pk); |
94 | RTPMessage *dequeue(JitterBuffer *q, int *success); | 90 | RTPMessage *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 | ||