1 /* Copyright (C) 2006 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
3 * based in parts on libfaad, Copyright (C) 2003-2005 M. Bakker,
7 /** \file aacdec_filter.c paraslash's aac (m4a) decoder. */
13 #include "portable_io.h"
16 #include "buffer_tree.h"
21 /** Give up decoding after that many errors. */
25 * data specific to the aacdec filter
27 * \sa \ref filter, \ref filter_node.
29 struct private_aacdec_data {
30 /** the return value of aac_open */
31 NeAACDecHandle handle;
32 /** whether this instance of the aac decoder is already initialized */
34 /** number of times the decoder returned an error */
36 /** number of bytes already consumed from the imput stream */
37 size_t consumed_total;
38 /** The number of channels of the current stream. */
39 unsigned int channels;
40 /** Current sample rate in Hz. */
41 unsigned int sample_rate;
44 static int aacdec_execute(const struct btr_node *btrn, const char *cmd,
47 struct filter_node *fn = btr_context(btrn);
48 struct private_aacdec_data *padd = fn->private_data;
50 return decoder_execute(cmd, padd->sample_rate, padd->channels, result);
53 static void aacdec_open(struct filter_node *fn)
55 NeAACDecConfigurationPtr c;
56 struct private_aacdec_data *padd = zalloc(sizeof(*padd));
58 padd->handle = NeAACDecOpen();
59 c = NeAACDecGetCurrentConfiguration(padd->handle);
60 c->defObjectType = LC;
61 c->outputFormat = FAAD_FMT_16BIT;
63 NeAACDecSetConfiguration(padd->handle, c);
65 fn->private_data = padd;
69 static void aacdec_close(struct filter_node *fn)
71 struct private_aacdec_data *padd = fn->private_data;
73 NeAACDecClose(padd->handle);
75 fn->private_data = NULL;
78 static int aacdec_post_monitor(__a_unused struct sched *s, void *context)
80 struct filter_node *fn = context;
81 struct btr_node *btrn = fn->btrn;
82 struct private_aacdec_data *padd = fn->private_data;
84 char *inbuf, *outbuf, *btrbuf;
85 size_t len, consumed, loaded = 0;
86 NeAACDecFrameInfo frame_info;
89 ret = btr_node_status(btrn, fn->min_iqs, BTR_NT_INTERNAL);
94 btr_merge(btrn, fn->min_iqs);
95 len = btr_next_buffer(btrn, &inbuf);
96 len = PARA_MIN(len, (size_t)8192);
98 if (!padd->initialized) {
99 unsigned long rate = 0;
100 unsigned char channels = 0;
101 ret = NeAACDecInit(padd->handle, (unsigned char *)inbuf,
102 len, &rate, &channels);
103 PARA_INFO_LOG("decoder init: %d\n", ret);
105 ret = -E_AACDEC_INIT;
109 padd->sample_rate = rate;
110 padd->channels = channels;
111 PARA_INFO_LOG("rate: %u, channels: %u\n",
112 padd->sample_rate, padd->channels);
113 padd->initialized = true;
117 //PARA_CRIT_LOG("consumed: %zu (%zu + %zu), have: %zu\n", padd->consumed_total + consumed,
118 // padd->consumed_total, consumed, len - consumed);
119 outbuf = NeAACDecDecode(padd->handle, &frame_info,
120 (unsigned char *)inbuf + consumed, len - consumed);
121 if (frame_info.error) {
122 int err = frame_info.error;
124 if (padd->error_count++ > MAX_ERRORS)
126 PARA_NOTICE_LOG("error #%u: (%s)\n", padd->error_count,
127 NeAACDecGetErrorMessage(err));
128 PARA_NOTICE_LOG("consumed (total, buffer, frame): "
130 padd->consumed_total, consumed,
131 frame_info.bytesconsumed);
132 consumed++; /* just eat one byte and hope for the best */
135 padd->error_count = 0;
136 //PARA_CRIT_LOG("decoder ate %lu\n", frame_info.bytesconsumed);
137 consumed += frame_info.bytesconsumed;
138 if (!frame_info.samples)
140 btrbuf = arr_alloc(2, frame_info.samples);
141 for (i = 0; i < frame_info.samples; i++) {
142 short sh = ((short *)outbuf)[i];
143 write_int16_host_endian(btrbuf + loaded, sh);
146 btr_add_output(btrbuf, loaded, btrn);
148 btr_consume(btrn, consumed);
149 padd->consumed_total += consumed;
155 btr_remove_node(&fn->btrn);
159 const struct filter lsg_filter_cmd_com_aacdec_user_data = {
161 .close = aacdec_close,
162 .pre_monitor = generic_filter_pre_monitor,
163 .post_monitor = aacdec_post_monitor,
164 .execute = aacdec_execute