Codebase list squeezelite / 74b08e7
add wma and alac support via ffmpeg Adrian Smith 10 years ago
5 changed file(s) with 801 addition(s) and 5 deletion(s). Raw diff Collapse all Expand all
22 LDFLAGS ?= -lasound -lpthread -lm -ldl -lrt
33 EXECUTABLE ?= squeezelite
44
5 SOURCES = main.c slimproto.c utils.c output.c buffer.c stream.c decode.c process.c resample.c flac.c pcm.c mad.c vorbis.c faad.c mpg.c
6 DEPS = squeezelite.h
5 SOURCES = main.c slimproto.c utils.c output.c buffer.c stream.c decode.c process.c resample.c flac.c pcm.c mad.c vorbis.c faad.c mpg.c ffmpeg.c
6 DEPS = squeezelite.h slimproto.h
77
88 OBJECTS = $(SOURCES:.c=.o)
99
130130 // register codecs
131131 // alc,wma,wmap,wmal,aac,spt,ogg,ogf,flc,aif,pcm,mp3
132132 i = 0;
133 #if FFMPEG
134 if (!opt || strstr(opt, "alac")) codecs[i++] = register_ff("alc");
135 if (!opt || strstr(opt, "wma")) codecs[i++] = register_ff("wma");
136 #endif
133137 if (!opt || strstr(opt, "aac")) codecs[i++] = register_faad();
134138 if (!opt || strstr(opt, "ogg")) codecs[i++] = register_vorbis();
135139 if (!opt || strstr(opt, "flac")) codecs[i++] = register_flac();
0 /*
1 * Squeezelite - lightweight headless squeezebox emulator
2 *
3 * (c) Adrian Smith 2012, 2013, triode1@btinternet.com
4 *
5 * This program is free software: you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation, either version 3 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program. If not, see <http://www.gnu.org/licenses/>.
17 *
18 */
19
20 #include "squeezelite.h"
21
22 #if FFMPEG
23
24 #include <libavformat/avformat.h>
25 #include <libavcodec/avcodec.h>
26
27 // we try to load a range of ffmpeg library versions
28 // note that this file must be compiled with header files of the same major version as the library loaded
29 // (as structs accessed may change between major versions)
30
31 #define LIBAVUTIL "libavutil.so"
32 #define LIBAVUTIL_MAX 52
33 #define LIBAVUTIL_MIN 51
34
35 #define LIBAVCODEC "libavcodec.so"
36 #define LIBAVCODEC_MAX 55
37 #define LIBAVCODEC_MIN 53
38
39 #define LIBAVFORMAT "libavformat.so"
40 #define LIBAVFORMAT_MAX 55
41 #define LIBAVFORMAT_MIN 53
42
43
44 #define READ_SIZE 4096 * 4 // this is large enough to ensure ffmpeg always gets new data when decode is called
45 #define WRITE_SIZE 256 * 1024 // FIXME - make smaller, but still to absorb max wma output
46
47 // FIXME - do we need to align these params as per ffmpeg on i386?
48 #define attribute_align_arg
49
50 struct ff_s {
51 // state for ffmpeg decoder
52 bool wma;
53 u8_t wma_mmsh;
54 u8_t wma_playstream;
55 u8_t wma_metadatastream;
56 u8_t *readbuf;
57 bool end_of_stream;
58 AVInputFormat *input_format;
59 AVFormatContext *formatC;
60 AVCodecContext *codecC;
61 AVFrame *frame;
62 AVPacket *avpkt;
63 unsigned mmsh_bytes_left;
64 unsigned mmsh_bytes_pad;
65 unsigned mmsh_packet_len;
66 // library versions
67 unsigned avcodec_v, avformat_v, avutil_v;
68 // ffmpeg symbols to be dynamically loaded from libavcodec
69 unsigned (* avcodec_version)(void);
70 AVCodec * (* avcodec_find_decoder)(int);
71 int attribute_align_arg (* avcodec_open2)(AVCodecContext *, const AVCodec *, AVDictionary **);
72 AVFrame * (* avcodec_alloc_frame)(void);
73 void (* avcodec_free_frame)(AVFrame *);
74 int attribute_align_arg (* avcodec_decode_audio4)(AVCodecContext *, AVFrame *, int *, const AVPacket *);
75 // ffmpeg symbols to be dynamically loaded from libavformat
76 unsigned (* avformat_version)(void);
77 AVFormatContext * (* avformat_alloc_context)(void);
78 void (* avformat_free_context)(AVFormatContext *);
79 int (* avformat_open_input)(AVFormatContext **, const char *, AVInputFormat *, AVDictionary **);
80 int (* avformat_find_stream_info)(AVFormatContext *, AVDictionary **);
81 AVIOContext * (* avio_alloc_context)(unsigned char *, int, int, void *,
82 int (*read_packet)(void *, uint8_t *, int), int (*write_packet)(void *, uint8_t *, int), int64_t (*seek)(void *, int64_t, int));
83 void (* av_init_packet)(AVPacket *);
84 void (* av_free_packet)(AVPacket *);
85 int (* av_read_frame)(AVFormatContext *, AVPacket *);
86 AVInputFormat * (* av_find_input_format)(const char *);
87 void (* av_register_all)(void);
88 // ffmpeg symbols to be dynamically loaded from libavutil
89 unsigned (* avutil_version)(void);
90 void (* av_log_set_callback)(void (*)(void*, int, const char*, va_list));
91 void (* av_log_set_level)(int);
92 int (* av_strerror)(int, char *, size_t);
93 void * (* av_malloc)(size_t);
94 void (* av_free)(void *);
95 };
96
97 static struct ff_s *ff;
98
99 extern log_level loglevel;
100
101 extern struct buffer *streambuf;
102 extern struct buffer *outputbuf;
103 extern struct streamstate stream;
104 extern struct outputstate output;
105 extern struct decodestate decode;
106 extern struct processstate process;
107
108 #define LOCK_S mutex_lock(streambuf->mutex)
109 #define UNLOCK_S mutex_unlock(streambuf->mutex)
110 #define LOCK_O mutex_lock(outputbuf->mutex)
111 #define UNLOCK_O mutex_unlock(outputbuf->mutex)
112 #if PROCESS
113 #define LOCK_O_direct if (decode.direct) mutex_lock(outputbuf->mutex)
114 #define UNLOCK_O_direct if (decode.direct) mutex_unlock(outputbuf->mutex)
115 #define IF_DIRECT(x) if (decode.direct) { x }
116 #define IF_PROCESS(x) if (!decode.direct) { x }
117 #else
118 #define LOCK_O_direct mutex_lock(outputbuf->mutex)
119 #define UNLOCK_O_direct mutex_unlock(outputbuf->mutex)
120 #define IF_DIRECT(x) { x }
121 #define IF_PROCESS(x)
122 #endif
123
124 // our own version of useful error function not included in earlier ffmpeg versions
125 static char *av__err2str(errnum) {
126 static char buf[64];
127 ff->av_strerror(errnum, buf, 64);
128 return buf;
129 }
130
131 // parser to extract asf data packet length from asf header
132 const u8_t header_guid[16] = { 0x30, 0x26, 0xB2, 0x75, 0x8E, 0x66, 0xCF, 0x11, 0xA6, 0xD9, 0x00, 0xAA, 0x00, 0x62, 0xCE, 0x6C };
133 const u8_t file_props_guid[16] = { 0xA1, 0xDC, 0xAB, 0x8C, 0x47, 0xA9, 0xCF, 0x11, 0x8E, 0xE4, 0x00, 0xC0, 0x0C, 0x20, 0x53, 0x65 };
134
135 static int _parse_packlen(void) {
136 int bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
137 u8_t *ptr = streambuf->readp;
138 int remain = 1;
139
140 while (bytes >= 24 && remain > 0) {
141 u32_t len = *(ptr+16) | *(ptr+17) << 8 | *(ptr+18) << 16 | *(ptr+19) << 24; // assume msb 32 bits are 0
142 if (!memcmp(ptr, header_guid, 16) && bytes >= 30) {
143 ptr += 30;
144 bytes -= 30;
145 remain = len - 30;
146 continue;
147 }
148 if (!memcmp(ptr, file_props_guid, 16) && len == 104) {
149 u32_t packlen = *(ptr+92) | *(ptr+93) << 8 | *(ptr+94) << 16 | *(ptr+95) << 24;
150 LOG_INFO("asf packet len: %u", packlen);
151 return packlen;
152 }
153 ptr += len;
154 bytes -= len;
155 remain -= len;
156 }
157
158 LOG_WARN("could not parse packet length");
159 return 0;
160 }
161
162 static int _read_data(void *opaque, u8_t *buffer, int buf_size) {
163 LOCK_S;
164
165 size_t bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
166 ff->end_of_stream = (stream.state <= DISCONNECT && bytes == 0);
167 bytes = min(bytes, buf_size);
168
169 // for chunked wma extract asf header and data frames from framing structure
170 // pad asf data frames to size of packet extracted from asf header
171 if (ff->wma_mmsh) {
172 unsigned chunk_type = 0, chunk_len = 0;
173
174 if (ff->mmsh_bytes_left) {
175 // bytes remaining from previous frame
176 if (bytes >= ff->mmsh_bytes_left) {
177 bytes = ff->mmsh_bytes_left;
178 ff->mmsh_bytes_left = 0;
179 } else {
180 ff->mmsh_bytes_left -= bytes;
181 }
182 } else if (ff->mmsh_bytes_pad) {
183 // add padding for previous frame
184 bytes = min(ff->mmsh_bytes_pad, buf_size);
185 memset(buffer, 0, bytes);
186 ff->mmsh_bytes_pad -= bytes;
187 UNLOCK_S;
188 return bytes;
189 } else if (bytes >= 12) {
190 // new chunk header
191 chunk_type = (*(streambuf->readp) & 0x7f) | *(streambuf->readp + 1) << 8;
192 chunk_len = *(streambuf->readp + 2) | *(streambuf->readp + 3) << 8;
193 _buf_inc_readp(streambuf, 12);
194 bytes -= 12;
195 } else if (_buf_used(streambuf) >= 12) {
196 // new chunk header split over end of streambuf, read in two
197 u8_t header[12];
198 memcpy(header, streambuf->readp, bytes);
199 _buf_inc_readp(streambuf, bytes);
200 memcpy(header + bytes, streambuf->readp, 12 - bytes);
201 _buf_inc_readp(streambuf, 12 - bytes);
202 chunk_type = (header[0] & 0x7f) | header[1] << 8;
203 chunk_len = header[2] | header[3] << 8;
204 bytes = min(_buf_used(streambuf), _buf_cont_read(streambuf));
205 bytes = min(bytes, buf_size);
206 } else {
207 // should not get here...
208 LOG_ERROR("chunk parser stalled bytes: %u %u", bytes, _buf_used(streambuf));
209 UNLOCK_S;
210 return 0;
211 }
212
213 if (chunk_type && chunk_len) {
214 if (chunk_type == 0x4824) {
215 // asf header - parse packet length
216 ff->mmsh_packet_len = _parse_packlen();
217 ff->mmsh_bytes_pad = 0;
218 } else if (chunk_type == 0x4424 && ff->mmsh_packet_len) {
219 // asf data packet - add padding
220 ff->mmsh_bytes_pad = ff->mmsh_packet_len - chunk_len + 8;
221 } else {
222 LOG_INFO("unknown chunk: %04x", chunk_type);
223 // other packet - no padding
224 ff->mmsh_bytes_pad = 0;
225 }
226
227 if (chunk_len - 8 <= bytes) {
228 bytes = chunk_len - 8;
229 ff->mmsh_bytes_left = 0;
230 } else {
231 ff->mmsh_bytes_left = chunk_len - 8 - bytes;
232 }
233 }
234
235 }
236
237 memcpy(buffer, streambuf->readp, bytes);
238
239 _buf_inc_readp(streambuf, bytes);
240
241 if (ff->mmsh_bytes_pad && bytes + ff->mmsh_bytes_pad < buf_size) {
242 memset(buffer + bytes, 0, ff->mmsh_bytes_pad);
243 bytes += ff->mmsh_bytes_pad;
244 ff->mmsh_bytes_pad = 0;
245 }
246
247 UNLOCK_S;
248
249 return bytes;
250 }
251
252 static decode_state ff_decode(void) {
253 int r, len, got_frame;
254 AVPacket pkt_c;
255 s32_t *optr = NULL;
256
257 if (decode.new_stream) {
258
259 AVIOContext *avio;
260 AVStream *av_stream;
261 AVCodec *codec;
262 int o;
263 int audio_stream = -1;
264
265 ff->mmsh_bytes_left = ff->mmsh_bytes_pad = ff->mmsh_packet_len = 0;
266
267 if (!ff->readbuf) {
268 ff->readbuf = ff->av_malloc(READ_SIZE + FF_INPUT_BUFFER_PADDING_SIZE);
269 }
270
271 avio = ff->avio_alloc_context(ff->readbuf, READ_SIZE, 0, NULL, _read_data, NULL, NULL);
272 avio->seekable = 0;
273
274 ff->formatC = ff->avformat_alloc_context();
275 if (ff->formatC == NULL) {
276 LOG_ERROR("null context");
277 return DECODE_ERROR;
278 }
279
280 ff->formatC->pb = avio;
281 ff->formatC->flags |= AVFMT_FLAG_CUSTOM_IO | AVFMT_FLAG_NOPARSE;
282
283 o = ff->avformat_open_input(&ff->formatC, "", ff->input_format, NULL);
284 if (o < 0) {
285 LOG_WARN("avformat_open_input: %d %s", o, av__err2str(o));
286 return DECODE_ERROR;
287 }
288
289 LOG_INFO("format: name:%s lname:%s", ff->formatC->iformat->name, ff->formatC->iformat->long_name);
290
291 o = ff->avformat_find_stream_info(ff->formatC, NULL);
292 if (o < 0) {
293 LOG_WARN("avformat_find_stream_info: %d %s", o, av__err2str(o));
294 return DECODE_ERROR;
295 }
296
297 if (ff->wma && ff->wma_playstream < ff->formatC->nb_streams) {
298 if (ff->formatC->streams[ff->wma_playstream]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
299 LOG_INFO("using wma stream sent from server: %i", ff->wma_playstream);
300 audio_stream = ff->wma_playstream;
301 }
302 }
303
304 if (audio_stream == -1) {
305 int i;
306 for (i = 0; i < ff->formatC->nb_streams; ++i) {
307 if (ff->formatC->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
308 audio_stream = i;
309 LOG_INFO("found stream: %i", i);
310 break;
311 }
312 }
313 }
314
315 if (audio_stream == -1) {
316 LOG_WARN("no audio stream found");
317 return DECODE_ERROR;
318 }
319
320 av_stream = ff->formatC->streams[audio_stream];
321
322 ff->codecC = av_stream->codec;
323
324 codec = ff->avcodec_find_decoder(ff->codecC->codec_id);
325
326 ff->avcodec_open2(ff->codecC, codec, NULL);
327
328 ff->frame = ff->avcodec_alloc_frame();
329
330 ff->avpkt = ff->av_malloc(sizeof(AVPacket));
331 if (ff->avpkt == NULL) {
332 LOG_ERROR("can't allocate avpkt");
333 return DECODE_ERROR;
334 }
335
336 ff->av_init_packet(ff->avpkt);
337 ff->avpkt->data = NULL;
338 ff->avpkt->size = 0;
339
340 LOCK_O;
341 LOG_INFO("setting track_start");
342 output.next_sample_rate = decode_newstream(ff->codecC->sample_rate, output.max_sample_rate);
343 output.track_start = outputbuf->writep;
344 if (output.fade_mode) _checkfade(true);
345 decode.new_stream = false;
346 UNLOCK_O;
347 }
348
349 got_frame = 0;
350
351 if ((r = ff->av_read_frame(ff->formatC, ff->avpkt)) < 0) {
352 if (r == AVERROR_EOF) {
353 if (ff->end_of_stream) {
354 LOG_INFO("decode complete");
355 return DECODE_COMPLETE;
356 } else {
357 LOG_INFO("codec end of file");
358 }
359 } else {
360 LOG_ERROR("av_read_frame error: %i %s", r, av__err2str(r));
361 }
362 return DECODE_RUNNING;
363 }
364
365 // clone packet as we are adjusting it
366 pkt_c = *ff->avpkt;
367
368 IF_PROCESS(
369 optr = (s32_t *)process.inbuf;
370 process.in_frames = 0;
371 );
372
373 while (pkt_c.size > 0 || got_frame) {
374
375 len = ff->avcodec_decode_audio4(ff->codecC, ff->frame, &got_frame, &pkt_c);
376 if (len < 0) {
377 LOG_ERROR("avcodec_decode_audio4 error: %i %s", len, av__err2str(len));
378 return DECODE_RUNNING;
379 }
380
381 pkt_c.data += len;
382 pkt_c.size -= len;
383
384 if (got_frame) {
385
386 s16_t *iptr16 = (s16_t *)ff->frame->data[0];
387 s32_t *iptr32 = (s32_t *)ff->frame->data[0];
388 s16_t *iptr16l = (s16_t *)ff->frame->data[0];
389 s16_t *iptr16r = (s16_t *)ff->frame->data[1];
390 s32_t *iptr32l = (s32_t *)ff->frame->data[0];
391 s32_t *iptr32r = (s32_t *)ff->frame->data[1];
392 float *iptrfl = (float *)ff->frame->data[0];
393 float *iptrfr = (float *)ff->frame->data[1];
394
395 frames_t frames = ff->frame->nb_samples;
396
397 LOG_SDEBUG("got audio channels: %u samples: %u format: %u", ff->codecC->channels, ff->frame->nb_samples,
398 ff->codecC->sample_fmt);
399
400 LOCK_O_direct;
401
402 while (frames > 0) {
403 frames_t count;
404 frames_t f;
405
406 IF_DIRECT(
407 optr = (s32_t *)outputbuf->writep;
408 f = min(_buf_space(outputbuf), _buf_cont_write(outputbuf)) / BYTES_PER_FRAME;
409 f = min(f, frames);
410 );
411
412 IF_PROCESS(
413 if (process.in_frames + frames > process.max_in_frames) {
414 LOG_WARN("exceeded process buffer size - dropping frames");
415 break;
416 }
417 f = frames;
418 );
419
420 count = f;
421
422 if (ff->codecC->channels == 2) {
423 if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16) {
424 while (count--) {
425 *optr++ = *iptr16++ << 16;
426 *optr++ = *iptr16++ << 16;
427 }
428 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32) {
429 while (count--) {
430 *optr++ = *iptr32++;
431 *optr++ = *iptr32++;
432 }
433 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16P) {
434 while (count--) {
435 *optr++ = *iptr16l++ << 16;
436 *optr++ = *iptr16r++ << 16;
437 }
438 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32P) {
439 while (count--) {
440 *optr++ = *iptr32l++;
441 *optr++ = *iptr32r++;
442 }
443 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_FLTP) {
444 while (count--) {
445 double scaledl = *iptrfl++ * 0x7fffffff;
446 double scaledr = *iptrfr++ * 0x7fffffff;
447 if (scaledl > 2147483647.0) scaledl = 2147483647.0;
448 if (scaledl < -2147483648.0) scaledl = -2147483648.0;
449 if (scaledr > 2147483647.0) scaledr = 2147483647.0;
450 if (scaledr < -2147483648.0) scaledr = -2147483648.0;
451 *optr++ = (s32_t)scaledl;
452 *optr++ = (s32_t)scaledr;
453 }
454 } else {
455 LOG_WARN("unsupported sample format: %u", ff->codecC->sample_fmt);
456 }
457 } else if (ff->codecC->channels == 1) {
458 if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16) {
459 while (count--) {
460 *optr++ = *iptr16 << 16;
461 *optr++ = *iptr16++ << 16;
462 }
463 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32) {
464 while (count--) {
465 *optr++ = *iptr32;
466 *optr++ = *iptr32++;
467 }
468 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S16P) {
469 while (count--) {
470 *optr++ = *iptr16l << 16;
471 *optr++ = *iptr16l++ << 16;
472 }
473 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_S32P) {
474 while (count--) {
475 *optr++ = *iptr32l;
476 *optr++ = *iptr32l++;
477 }
478 } else if (ff->codecC->sample_fmt == AV_SAMPLE_FMT_FLTP) {
479 while (count--) {
480 double scaled = *iptrfl++ * 0x7fffffff;
481 if (scaled > 2147483647.0) scaled = 2147483647.0;
482 if (scaled < -2147483648.0) scaled = -2147483648.0;
483 *optr++ = (s32_t)scaled;
484 *optr++ = (s32_t)scaled;
485 }
486 } else {
487 LOG_WARN("unsupported sample format: %u", ff->codecC->sample_fmt);
488 }
489 } else {
490 LOG_WARN("unsupported number of channels");
491 }
492
493 frames -= f;
494
495 IF_DIRECT(
496 _buf_inc_writep(outputbuf, f * BYTES_PER_FRAME);
497 );
498
499 IF_PROCESS(
500 process.in_frames += f;
501 );
502 }
503
504 UNLOCK_O_direct;
505 }
506 }
507
508 ff->av_free_packet(ff->avpkt);
509
510 return DECODE_RUNNING;
511 }
512
513 static void _free_ff_data(void) {
514 if (ff->formatC) {
515 if (ff->formatC->pb) ff->av_free(ff->formatC->pb);
516 ff->avformat_free_context(ff->formatC);
517 ff->formatC = NULL;
518 }
519
520 if (ff->frame) {
521 // ffmpeg version dependant free function
522 ff->avcodec_free_frame ? ff->avcodec_free_frame(ff->frame) : ff->av_free(ff->frame);
523 ff->frame = NULL;
524 }
525
526 if (ff->avpkt) {
527 ff->av_free_packet(ff->avpkt);
528 ff->av_free(ff->avpkt);
529 ff->avpkt = NULL;
530 }
531 }
532
533 static void ff_open_wma(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
534 _free_ff_data();
535
536 ff->input_format = ff->av_find_input_format("asf");
537 if (ff->input_format == NULL) {
538 LOG_ERROR("asf format not supported by ffmpeg library");
539 }
540
541 ff->wma = true;
542 ff->wma_mmsh = size - '0';
543 ff->wma_playstream = rate - 1;
544 ff->wma_metadatastream = chan != '?' ? chan : 0;
545
546 LOG_INFO("open wma chunking: %u playstream: %u metadatastream: %u", ff->wma_mmsh, ff->wma_playstream, ff->wma_metadatastream);
547 }
548
549 static void ff_open_alac(u8_t size, u8_t rate, u8_t chan, u8_t endianness) {
550 _free_ff_data();
551
552 ff->input_format = ff->av_find_input_format("mp4");
553 if (ff->input_format == NULL) {
554 LOG_ERROR("mp4 format not supported by ffmpeg library");
555 }
556
557 ff->wma = false;
558 ff->wma_mmsh = 0;
559
560 LOG_INFO("open alac");
561 }
562
563 static void ff_close(void) {
564 _free_ff_data();
565
566 if (ff->readbuf) {
567 ff->av_free(ff->readbuf);
568 ff->readbuf = NULL;
569 }
570 }
571
572 static bool load_ff() {
573 void *handle_codec = NULL, *handle_format = NULL, *handle_util = NULL;
574 char name[30];
575 char *err;
576 int i;
577
578 // attempt to load newest known versions of libraries first
579 for (i = LIBAVCODEC_MAX; i >= LIBAVCODEC_MIN && !handle_codec; --i) {
580 sprintf(name, "%s.%d", LIBAVCODEC, i);
581 handle_codec = dlopen(name, RTLD_NOW);
582 }
583 if (!handle_codec) {
584 LOG_INFO("dlerror: %s", dlerror());
585 return false;
586 }
587
588 for (i = LIBAVFORMAT_MAX; i >= LIBAVFORMAT_MIN && !handle_format; --i) {
589 sprintf(name, "%s.%d", LIBAVFORMAT, i);
590 handle_format = dlopen(name, RTLD_NOW);
591 }
592 if (!handle_format) {
593 LOG_INFO("dlerror: %s", dlerror());
594 return false;
595 }
596
597 for (i = LIBAVUTIL_MAX; i >= LIBAVUTIL_MIN && !handle_util; --i) {
598 sprintf(name, "%s.%d", LIBAVUTIL, i);
599 handle_util = dlopen(name, RTLD_NOW);
600 }
601 if (!handle_util) {
602 LOG_INFO("dlerror: %s", dlerror());
603 return false;
604 }
605
606 ff = malloc(sizeof(struct ff_s));
607 memset(ff, 0, sizeof(struct ff_s));
608
609 ff->avcodec_version = dlsym(handle_codec, "avcodec_version");
610 ff->avcodec_find_decoder = dlsym(handle_codec, "avcodec_find_decoder");
611 ff->avcodec_open2 = dlsym(handle_codec, "avcodec_open2");
612 ff->avcodec_alloc_frame = dlsym(handle_codec, "avcodec_alloc_frame");
613 ff->avcodec_free_frame = dlsym(handle_codec, "avcodec_free_frame");
614 ff->avcodec_decode_audio4 = dlsym(handle_codec, "avcodec_decode_audio4");
615
616 if ((err = dlerror()) != NULL) {
617 LOG_INFO("dlerror: %s", err);
618 return false;
619 }
620
621 ff->avcodec_v = ff->avcodec_version();
622 LOG_INFO("loaded "LIBAVCODEC" (%u.%u.%u)", ff->avcodec_v >> 16, (ff->avcodec_v >> 8) & 0xff, ff->avcodec_v & 0xff);
623 if (ff->avcodec_v >> 16 != LIBAVCODEC_VERSION_MAJOR) {
624 LOG_WARN("error: library major version (%u) differs from build headers (%u)", ff->avcodec_v >> 16, LIBAVCODEC_VERSION_MAJOR);
625 return false;
626 }
627
628 ff->avformat_version = dlsym(handle_format, "avformat_version");
629 ff->avformat_alloc_context = dlsym(handle_format, "avformat_alloc_context");
630 ff->avformat_free_context = dlsym(handle_format, "avformat_free_context");
631 ff->avformat_open_input = dlsym(handle_format, "avformat_open_input");
632 ff->avformat_find_stream_info = dlsym(handle_format, "avformat_find_stream_info");
633 ff->avio_alloc_context = dlsym(handle_format, "avio_alloc_context");
634 ff->av_init_packet = dlsym(handle_format, "av_init_packet");
635 ff->av_free_packet = dlsym(handle_format, "av_free_packet");
636 ff->av_read_frame = dlsym(handle_format, "av_read_frame");
637 ff->av_find_input_format= dlsym(handle_format, "av_find_input_format");
638 ff->av_register_all = dlsym(handle_format, "av_register_all");
639
640 if ((err = dlerror()) != NULL) {
641 LOG_INFO("dlerror: %s", err);
642 return false;
643 }
644
645 ff->avformat_v = ff->avformat_version();
646 LOG_INFO("loaded "LIBAVFORMAT" (%u.%u.%u)", ff->avformat_v >> 16, (ff->avformat_v >> 8) & 0xff, ff->avformat_v & 0xff);
647 if (ff->avformat_v >> 16 != LIBAVFORMAT_VERSION_MAJOR) {
648 LOG_WARN("error: library major version (%u) differs from build headers (%u)", ff->avformat_v >> 16, LIBAVFORMAT_VERSION_MAJOR);
649 return false;
650 }
651
652 ff->avutil_version = dlsym(handle_util, "avutil_version");
653 ff->av_log_set_callback = dlsym(handle_util, "av_log_set_callback");
654 ff->av_log_set_level = dlsym(handle_util, "av_log_set_level");
655 ff->av_strerror = dlsym(handle_util, "av_strerror");
656 ff->av_malloc = dlsym(handle_util, "av_malloc");
657 ff->av_free = dlsym(handle_util, "av_free");
658
659 if ((err = dlerror()) != NULL) {
660 LOG_INFO("dlerror: %s", err);
661 return false;
662 }
663
664 ff->avutil_v = ff->avutil_version();
665 LOG_INFO("loaded "LIBAVUTIL" (%u.%u.%u)", ff->avutil_v >> 16, (ff->avutil_v >> 8) & 0xff, ff->avutil_v & 0xff);
666 if (ff->avutil_v >> 16 != LIBAVUTIL_VERSION_MAJOR) {
667 LOG_WARN("error: library major version (%u) differs from build headers (%u)", ff->avutil_v >> 16, LIBAVUTIL_VERSION_MAJOR);
668 return false;
669 }
670
671 return true;
672 }
673
674 static int ff_log_level = 0;
675
676 void av_err_callback(void *avcl, int level, const char *fmt, va_list vl) {
677 if (level > ff_log_level) return;
678 fprintf(stderr, "%s ffmpeg: ", logtime());
679 vfprintf(stderr, fmt, vl);
680 fflush(stderr);
681 }
682
683 static bool registered = false;
684
685 struct codec *register_ff(const char *codec) {
686 if (!registered) {
687
688 if (!load_ff()) {
689 return NULL;
690 }
691
692 switch (loglevel) {
693 case lERROR:
694 ff_log_level = AV_LOG_ERROR; break;
695 case lWARN:
696 ff_log_level = AV_LOG_WARNING; break;
697 case lINFO:
698 ff_log_level = AV_LOG_INFO; break;
699 case lDEBUG:
700 ff_log_level = AV_LOG_VERBOSE; break;
701 default: break;
702 }
703
704 ff->av_log_set_callback(av_err_callback);
705
706 ff->av_register_all();
707
708 registered = true;
709 }
710
711 if (!strcmp(codec, "wma")) {
712
713 static struct codec ret = {
714 'w', // id
715 "wma,wmap,wmal", // types
716 READ_SIZE, // min read
717 WRITE_SIZE, // min space
718 ff_open_wma, // open
719 ff_close, // close
720 ff_decode, // decode
721 };
722
723 return &ret;
724 }
725
726 if (!strcmp(codec, "alc")) {
727
728 static struct codec ret = {
729 'l', // id
730 "alc", // types
731 READ_SIZE, // min read
732 WRITE_SIZE, // min space
733 ff_open_alac,// open
734 ff_close, // close
735 ff_decode, // decode
736 };
737
738 return &ret;
739 }
740
741 return NULL;
742 }
743
744 #endif
4040 #endif
4141 #endif
4242 " -b <stream>:<output>\tSpecify internal Stream and Output buffer sizes in Kbytes\n"
43 " -c <codec1>,<codec2>\tRestrict codecs to those specified, otherwise load all available codecs; known codecs: flac,pcm,mp3,ogg,aac (mad,mpg for specific mp3 codec)\n"
43 " -c <codec1>,<codec2>\tRestrict codecs to those specified, otherwise load all available codecs; known codecs: "
44 #if FFMPEG
45 "flac,pcm,mp3,ogg,aac,wma,alac (mad,mpg for specific mp3 codec)\n"
46 #else
47 "flac,pcm,mp3,ogg,aac (mad,mpg for specific mp3 codec)\n"
48 #endif
4449 " -d <log>=<level>\tSet logging level, logs: all|slimproto|stream|decode|output, level: info|debug|sdebug\n"
4550 " -f <logfile>\t\tWrite debug to logfile\n"
4651 " -m <mac addr>\t\tSet mac address, format: ab:cd:ef:12:34:56\n"
6368 " -z \t\t\tDaemonize\n"
6469 #endif
6570 " -t \t\t\tLicense terms\n"
66 "\n",
71 "\n"
72 "Build options: "
73 #if LINUX
74 "LINUX"
75 #endif
76 #if WIN
77 "WIN"
78 #endif
79 #if OSX
80 "OSX"
81 #endif
82 #if ALSA
83 " ALSA"
84 #endif
85 #if PORTAUDIO
86 " PORTAUDIO"
87 #endif
88 #if EVENTFD
89 " EVENTFD"
90 #endif
91 #if SELFPIPE
92 " SELFPIPE"
93 #endif
94 #if WINEVENT
95 " WINEVENT"
96 #endif
97 #if RESAMPLE
98 " RESAMPLE"
99 #endif
100 #if FFMPEG
101 " FFMPEG"
102 #endif
103 "\n\n",
67104 argv0);
68105 }
69106
6767 #define RESAMPLE 1 // resampling
6868 #define PROCESS 1 // any sample processing (only resampling at present)
6969 #else
70 #define RESAMPLE 0
7071 #define PROCESS 0
72 #endif
73
74 #if LINUX && defined(FFMPEG)
75 #undef FFMPEG
76 #define FFMPEG 1 // ffmpeg only supported on linux at present
77 #else
78 #undef FFMPEG
79 #define FFMPEG 0
7180 #endif
7281
7382 // dynamically loaded libraries
476485 void _pa_open(void);
477486
478487 // codecs
479 #define MAX_CODECS 6
488 #define MAX_CODECS 8
480489
481490 struct codec *register_flac(void);
482491 struct codec *register_pcm(void);
484493 struct codec *register_mpg(void);
485494 struct codec *register_vorbis(void);
486495 struct codec *register_faad(void);
496 struct codec *register_ff(const char *codec);