Move src to src/lib, include to src/include, test to src/test.
[deb_shairplay.git] / src / lib / raop_buffer.c
1 #include <stdlib.h>
2 #include <string.h>
3 #include <assert.h>
4 #include <math.h>
5
6 #include "raop_buffer.h"
7 #include "raop_rtp.h"
8 #include "utils.h"
9
10 #include <stdint.h>
11 #include "crypto/crypto.h"
12 #include "alac/alac.h"
13
14 #define RAOP_BUFFER_LENGTH 16
15
16 typedef struct {
17 /* Packet available */
18 int available;
19
20 /* RTP header */
21 unsigned char flags;
22 unsigned char type;
23 unsigned short seqnum;
24 unsigned int timestamp;
25 unsigned int ssrc;
26
27 /* Audio buffer of valid length */
28 int audio_buffer_size;
29 int audio_buffer_len;
30 void *audio_buffer;
31 } raop_buffer_entry_t;
32
33 struct raop_buffer_s {
34 /* AES key and IV */
35 unsigned char aeskey[RAOP_AESKEY_LEN];
36 unsigned char aesiv[RAOP_AESIV_LEN];
37
38 /* ALAC decoder */
39 ALACSpecificConfig alacConfig;
40 alac_file *alac;
41
42 /* First and last seqnum */
43 int is_empty;
44 unsigned short first_seqnum;
45 unsigned short last_seqnum;
46
47 /* RTP buffer entries */
48 raop_buffer_entry_t entries[RAOP_BUFFER_LENGTH];
49
50 /* Buffer of all audio buffers */
51 int buffer_size;
52 void *buffer;
53 };
54
55
56
57 static int
58 get_fmtp_info(ALACSpecificConfig *config, const char *fmtp)
59 {
60 int intarr[12];
61 char *strptr;
62 int i;
63
64 /* Parse fmtp string to integers */
65 strptr = strdup(fmtp);
66 for (i=0; i<12; i++) {
67 if (strptr == NULL) {
68 free(strptr);
69 return -1;
70 }
71 intarr[i] = atoi(utils_strsep(&strptr, " "));
72 }
73 free(strptr);
74 strptr = NULL;
75
76 /* Fill the config struct */
77 config->frameLength = intarr[1];
78 config->compatibleVersion = intarr[2];
79 config->bitDepth = intarr[3];
80 config->pb = intarr[4];
81 config->mb = intarr[5];
82 config->kb = intarr[6];
83 config->numChannels = intarr[7];
84 config->maxRun = intarr[8];
85 config->maxFrameBytes = intarr[9];
86 config->avgBitRate = intarr[10];
87 config->sampleRate = intarr[11];
88
89 /* Validate supported audio types */
90 if (config->bitDepth != 16) {
91 return -2;
92 }
93 if (config->numChannels != 2) {
94 return -3;
95 }
96
97 return 0;
98 }
99
100 static void
101 set_decoder_info(alac_file *alac, ALACSpecificConfig *config)
102 {
103 unsigned char decoder_info[48];
104 memset(decoder_info, 0, sizeof(decoder_info));
105
106 #define SET_UINT16(buf, value)do{\
107 (buf)[0] = (unsigned char)((value) >> 8);\
108 (buf)[1] = (unsigned char)(value);\
109 }while(0)
110
111 #define SET_UINT32(buf, value)do{\
112 (buf)[0] = (unsigned char)((value) >> 24);\
113 (buf)[1] = (unsigned char)((value) >> 16);\
114 (buf)[2] = (unsigned char)((value) >> 8);\
115 (buf)[3] = (unsigned char)(value);\
116 }while(0)
117
118 /* Construct decoder info buffer */
119 SET_UINT32(&decoder_info[24], config->frameLength);
120 decoder_info[28] = config->compatibleVersion;
121 decoder_info[29] = config->bitDepth;
122 decoder_info[30] = config->pb;
123 decoder_info[31] = config->mb;
124 decoder_info[32] = config->kb;
125 decoder_info[33] = config->numChannels;
126 SET_UINT16(&decoder_info[34], config->maxRun);
127 SET_UINT32(&decoder_info[36], config->maxFrameBytes);
128 SET_UINT32(&decoder_info[40], config->avgBitRate);
129 SET_UINT32(&decoder_info[44], config->sampleRate);
130 alac_set_info(alac, (char *) decoder_info);
131 }
132
133 raop_buffer_t *
134 raop_buffer_init(const char *fmtp,
135 const unsigned char *aeskey,
136 const unsigned char *aesiv)
137 {
138 raop_buffer_t *raop_buffer;
139 int audio_buffer_size;
140 ALACSpecificConfig *alacConfig;
141 int i;
142
143 assert(fmtp);
144 assert(aeskey);
145 assert(aesiv);
146
147 raop_buffer = calloc(1, sizeof(raop_buffer_t));
148 if (!raop_buffer) {
149 return NULL;
150 }
151
152 /* Parse fmtp information */
153 alacConfig = &raop_buffer->alacConfig;
154 if (get_fmtp_info(alacConfig, fmtp) < 0) {
155 free(raop_buffer);
156 return NULL;
157 }
158
159 /* Allocate the output audio buffers */
160 audio_buffer_size = alacConfig->frameLength *
161 alacConfig->numChannels *
162 alacConfig->bitDepth/8;
163 raop_buffer->buffer_size = audio_buffer_size *
164 RAOP_BUFFER_LENGTH;
165 raop_buffer->buffer = malloc(raop_buffer->buffer_size);
166 if (!raop_buffer->buffer) {
167 free(raop_buffer);
168 return NULL;
169 }
170 for (i=0; i<RAOP_BUFFER_LENGTH; i++) {
171 raop_buffer_entry_t *entry = &raop_buffer->entries[i];
172 entry->audio_buffer_size = audio_buffer_size;
173 entry->audio_buffer_len = 0;
174 entry->audio_buffer = raop_buffer->buffer+i*audio_buffer_size;
175 }
176
177 /* Initialize ALAC decoder */
178 raop_buffer->alac = create_alac(alacConfig->bitDepth,
179 alacConfig->numChannels);
180 if (!raop_buffer->alac) {
181 free(raop_buffer->buffer);
182 free(raop_buffer);
183 return NULL;
184 }
185 set_decoder_info(raop_buffer->alac, alacConfig);
186
187 /* Initialize AES keys */
188 memcpy(raop_buffer->aeskey, aeskey, RAOP_AESKEY_LEN);
189 memcpy(raop_buffer->aesiv, aesiv, RAOP_AESIV_LEN);
190
191 /* Mark buffer as empty */
192 raop_buffer->is_empty = 1;
193 return raop_buffer;
194 }
195
196 void
197 raop_buffer_destroy(raop_buffer_t *raop_buffer)
198 {
199 if (raop_buffer) {
200 free(raop_buffer->buffer);
201 free(raop_buffer->alac);
202 free(raop_buffer);
203 }
204 }
205
206 const ALACSpecificConfig *
207 raop_buffer_get_config(raop_buffer_t *raop_buffer)
208 {
209 assert(raop_buffer);
210
211 return &raop_buffer->alacConfig;
212 }
213
214 static short
215 seqnum_cmp(unsigned short s1, unsigned short s2)
216 {
217 return (s1 - s2);
218 }
219
220 int
221 raop_buffer_queue(raop_buffer_t *raop_buffer, unsigned char *data, unsigned short datalen, int use_seqnum)
222 {
223 unsigned char packetbuf[RAOP_PACKET_LEN];
224 unsigned short seqnum;
225 raop_buffer_entry_t *entry;
226 int encryptedlen;
227 AES_CTX aes_ctx;
228 int outputlen;
229
230 assert(raop_buffer);
231
232 /* Check packet data length is valid */
233 if (datalen < 12 || datalen > RAOP_PACKET_LEN) {
234 return -1;
235 }
236
237 /* Get correct seqnum for the packet */
238 if (use_seqnum) {
239 seqnum = (data[2] << 8) | data[3];
240 } else {
241 seqnum = raop_buffer->first_seqnum;
242 }
243
244 /* If this packet is too late, just skip it */
245 if (!raop_buffer->is_empty && seqnum_cmp(seqnum, raop_buffer->first_seqnum) < 0) {
246 return 0;
247 }
248
249 /* Check that there is always space in the buffer, otherwise flush */
250 if (seqnum_cmp(seqnum, raop_buffer->first_seqnum+RAOP_BUFFER_LENGTH) >= 0) {
251 raop_buffer_flush(raop_buffer, seqnum);
252 }
253
254 /* Get entry corresponding our seqnum */
255 entry = &raop_buffer->entries[seqnum % RAOP_BUFFER_LENGTH];
256 if (entry->available && seqnum_cmp(entry->seqnum, seqnum) == 0) {
257 /* Packet resend, we can safely ignore */
258 return 0;
259 }
260
261 /* Update the raop_buffer entry header */
262 entry->flags = data[0];
263 entry->type = data[1];
264 entry->seqnum = seqnum;
265 entry->timestamp = (data[4] << 24) | (data[5] << 16) |
266 (data[6] << 8) | data[7];
267 entry->ssrc = (data[8] << 24) | (data[9] << 16) |
268 (data[10] << 8) | data[11];
269 entry->available = 1;
270
271 /* Decrypt audio data */
272 encryptedlen = (datalen-12)/16*16;
273 AES_set_key(&aes_ctx, raop_buffer->aeskey, raop_buffer->aesiv, AES_MODE_128);
274 AES_convert_key(&aes_ctx);
275 AES_cbc_decrypt(&aes_ctx, &data[12], packetbuf, encryptedlen);
276 memcpy(packetbuf+encryptedlen, &data[12+encryptedlen], datalen-12-encryptedlen);
277
278 /* Decode ALAC audio data */
279 outputlen = entry->audio_buffer_size;
280 decode_frame(raop_buffer->alac, packetbuf, entry->audio_buffer, &outputlen);
281 entry->audio_buffer_len = outputlen;
282
283 /* Update the raop_buffer seqnums */
284 if (raop_buffer->is_empty) {
285 raop_buffer->first_seqnum = seqnum;
286 raop_buffer->last_seqnum = seqnum;
287 raop_buffer->is_empty = 0;
288 }
289 if (seqnum_cmp(seqnum, raop_buffer->last_seqnum) > 0) {
290 raop_buffer->last_seqnum = seqnum;
291 }
292 return 1;
293 }
294
295 const void *
296 raop_buffer_dequeue(raop_buffer_t *raop_buffer, int *length, int no_resend)
297 {
298 short buflen;
299 raop_buffer_entry_t *entry;
300
301 /* Calculate number of entries in the current buffer */
302 buflen = seqnum_cmp(raop_buffer->last_seqnum, raop_buffer->first_seqnum)+1;
303
304 /* Cannot dequeue from empty buffer */
305 if (raop_buffer->is_empty || buflen <= 0) {
306 return NULL;
307 }
308
309 /* Get the first buffer entry for inspection */
310 entry = &raop_buffer->entries[raop_buffer->first_seqnum % RAOP_BUFFER_LENGTH];
311 if (no_resend) {
312 /* If we do no resends, always return the first entry */
313 } else if (!entry->available) {
314 /* Check how much we have space left in the buffer */
315 if (buflen < RAOP_BUFFER_LENGTH) {
316 /* Return nothing and hope resend gets on time */
317 return NULL;
318 }
319 /* Risk of buffer overrun, return empty buffer */
320 }
321
322 /* Update buffer and validate entry */
323 raop_buffer->first_seqnum += 1;
324 if (!entry->available) {
325 /* Return an empty audio buffer to skip audio */
326 *length = entry->audio_buffer_size;
327 memset(entry->audio_buffer, 0, *length);
328 return entry->audio_buffer;
329 }
330 entry->available = 0;
331
332 /* Return entry audio buffer */
333 *length = entry->audio_buffer_len;
334 entry->audio_buffer_len = 0;
335 return entry->audio_buffer;
336 }
337
338 void
339 raop_buffer_handle_resends(raop_buffer_t *raop_buffer, raop_resend_cb_t resend_cb, void *opaque)
340 {
341 raop_buffer_entry_t *entry;
342
343 assert(raop_buffer);
344 assert(resend_cb);
345
346 if (seqnum_cmp(raop_buffer->first_seqnum, raop_buffer->last_seqnum) < 0) {
347 int seqnum, count;
348
349 for (seqnum=raop_buffer->first_seqnum; seqnum_cmp(seqnum, raop_buffer->last_seqnum)<0; seqnum++) {
350 entry = &raop_buffer->entries[seqnum % RAOP_BUFFER_LENGTH];
351 if (entry->available) {
352 break;
353 }
354 }
355 if (seqnum_cmp(seqnum, raop_buffer->first_seqnum) == 0) {
356 return;
357 }
358 count = seqnum_cmp(seqnum, raop_buffer->first_seqnum);
359 resend_cb(opaque, raop_buffer->first_seqnum, count);
360 }
361 }
362
363 void
364 raop_buffer_flush(raop_buffer_t *raop_buffer, int next_seq)
365 {
366 int i;
367
368 assert(raop_buffer);
369
370 for (i=0; i<RAOP_BUFFER_LENGTH; i++) {
371 raop_buffer->entries[i].available = 0;
372 raop_buffer->entries[i].audio_buffer_len = 0;
373 }
374 if (next_seq < 0 || next_seq > 0xffff) {
375 raop_buffer->is_empty = 1;
376 } else {
377 raop_buffer->first_seqnum = next_seq;
378 raop_buffer->last_seqnum = next_seq-1;
379 }
380 }