summaryrefslogtreecommitdiff
path: root/apps/codecs/libmad/decoder.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2005-02-15 18:29:42 +0000
committerDave Chapman <dave@dchapman.com>2005-02-15 18:29:42 +0000
commit98c4f65f3a6c0de9a0bc24db38757939cb851115 (patch)
tree605bc7b4c01e9b3ed689b0edf871a543a06166bc /apps/codecs/libmad/decoder.c
parent6416099f3fb486f21caea3673a362b63e26dd314 (diff)
downloadrockbox-98c4f65f3a6c0de9a0bc24db38757939cb851115.tar.gz
rockbox-98c4f65f3a6c0de9a0bc24db38757939cb851115.zip
Initial check-in of unmodified libmad code (libmad-0.15.1b)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@5955 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/codecs/libmad/decoder.c')
-rw-r--r--apps/codecs/libmad/decoder.c582
1 files changed, 582 insertions, 0 deletions
diff --git a/apps/codecs/libmad/decoder.c b/apps/codecs/libmad/decoder.c
new file mode 100644
index 0000000000..efa95e31c8
--- /dev/null
+++ b/apps/codecs/libmad/decoder.c
@@ -0,0 +1,582 @@
1/*
2 * libmad - MPEG audio decoder library
3 * Copyright (C) 2000-2004 Underbit Technologies, Inc.
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 2 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, write to the Free Software
17 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 *
19 * $Id$
20 */
21
22# ifdef HAVE_CONFIG_H
23# include "config.h"
24# endif
25
26# include "global.h"
27
28# ifdef HAVE_SYS_TYPES_H
29# include <sys/types.h>
30# endif
31
32# ifdef HAVE_SYS_WAIT_H
33# include <sys/wait.h>
34# endif
35
36# ifdef HAVE_UNISTD_H
37# include <unistd.h>
38# endif
39
40# ifdef HAVE_FCNTL_H
41# include <fcntl.h>
42# endif
43
44# include <stdlib.h>
45
46# ifdef HAVE_ERRNO_H
47# include <errno.h>
48# endif
49
50# include "stream.h"
51# include "frame.h"
52# include "synth.h"
53# include "decoder.h"
54
55/*
56 * NAME: decoder->init()
57 * DESCRIPTION: initialize a decoder object with callback routines
58 */
59void mad_decoder_init(struct mad_decoder *decoder, void *data,
60 enum mad_flow (*input_func)(void *,
61 struct mad_stream *),
62 enum mad_flow (*header_func)(void *,
63 struct mad_header const *),
64 enum mad_flow (*filter_func)(void *,
65 struct mad_stream const *,
66 struct mad_frame *),
67 enum mad_flow (*output_func)(void *,
68 struct mad_header const *,
69 struct mad_pcm *),
70 enum mad_flow (*error_func)(void *,
71 struct mad_stream *,
72 struct mad_frame *),
73 enum mad_flow (*message_func)(void *,
74 void *, unsigned int *))
75{
76 decoder->mode = -1;
77
78 decoder->options = 0;
79
80 decoder->async.pid = 0;
81 decoder->async.in = -1;
82 decoder->async.out = -1;
83
84 decoder->sync = 0;
85
86 decoder->cb_data = data;
87
88 decoder->input_func = input_func;
89 decoder->header_func = header_func;
90 decoder->filter_func = filter_func;
91 decoder->output_func = output_func;
92 decoder->error_func = error_func;
93 decoder->message_func = message_func;
94}
95
96int mad_decoder_finish(struct mad_decoder *decoder)
97{
98# if defined(USE_ASYNC)
99 if (decoder->mode == MAD_DECODER_MODE_ASYNC && decoder->async.pid) {
100 pid_t pid;
101 int status;
102
103 close(decoder->async.in);
104
105 do
106 pid = waitpid(decoder->async.pid, &status, 0);
107 while (pid == -1 && errno == EINTR);
108
109 decoder->mode = -1;
110
111 close(decoder->async.out);
112
113 decoder->async.pid = 0;
114 decoder->async.in = -1;
115 decoder->async.out = -1;
116
117 if (pid == -1)
118 return -1;
119
120 return (!WIFEXITED(status) || WEXITSTATUS(status)) ? -1 : 0;
121 }
122# endif
123
124 return 0;
125}
126
127# if defined(USE_ASYNC)
128static
129enum mad_flow send_io(int fd, void const *data, size_t len)
130{
131 char const *ptr = data;
132 ssize_t count;
133
134 while (len) {
135 do
136 count = write(fd, ptr, len);
137 while (count == -1 && errno == EINTR);
138
139 if (count == -1)
140 return MAD_FLOW_BREAK;
141
142 len -= count;
143 ptr += count;
144 }
145
146 return MAD_FLOW_CONTINUE;
147}
148
149static
150enum mad_flow receive_io(int fd, void *buffer, size_t len)
151{
152 char *ptr = buffer;
153 ssize_t count;
154
155 while (len) {
156 do
157 count = read(fd, ptr, len);
158 while (count == -1 && errno == EINTR);
159
160 if (count == -1)
161 return (errno == EAGAIN) ? MAD_FLOW_IGNORE : MAD_FLOW_BREAK;
162 else if (count == 0)
163 return MAD_FLOW_STOP;
164
165 len -= count;
166 ptr += count;
167 }
168
169 return MAD_FLOW_CONTINUE;
170}
171
172static
173enum mad_flow receive_io_blocking(int fd, void *buffer, size_t len)
174{
175 int flags, blocking;
176 enum mad_flow result;
177
178 flags = fcntl(fd, F_GETFL);
179 if (flags == -1)
180 return MAD_FLOW_BREAK;
181
182 blocking = flags & ~O_NONBLOCK;
183
184 if (blocking != flags &&
185 fcntl(fd, F_SETFL, blocking) == -1)
186 return MAD_FLOW_BREAK;
187
188 result = receive_io(fd, buffer, len);
189
190 if (flags != blocking &&
191 fcntl(fd, F_SETFL, flags) == -1)
192 return MAD_FLOW_BREAK;
193
194 return result;
195}
196
197static
198enum mad_flow send(int fd, void const *message, unsigned int size)
199{
200 enum mad_flow result;
201
202 /* send size */
203
204 result = send_io(fd, &size, sizeof(size));
205
206 /* send message */
207
208 if (result == MAD_FLOW_CONTINUE)
209 result = send_io(fd, message, size);
210
211 return result;
212}
213
214static
215enum mad_flow receive(int fd, void **message, unsigned int *size)
216{
217 enum mad_flow result;
218 unsigned int actual;
219
220 if (*message == 0)
221 *size = 0;
222
223 /* receive size */
224
225 result = receive_io(fd, &actual, sizeof(actual));
226
227 /* receive message */
228
229 if (result == MAD_FLOW_CONTINUE) {
230 if (actual > *size)
231 actual -= *size;
232 else {
233 *size = actual;
234 actual = 0;
235 }
236
237 if (*size > 0) {
238 if (*message == 0) {
239 *message = malloc(*size);
240 if (*message == 0)
241 return MAD_FLOW_BREAK;
242 }
243
244 result = receive_io_blocking(fd, *message, *size);
245 }
246
247 /* throw away remainder of message */
248
249 while (actual && result == MAD_FLOW_CONTINUE) {
250 char sink[256];
251 unsigned int len;
252
253 len = actual > sizeof(sink) ? sizeof(sink) : actual;
254
255 result = receive_io_blocking(fd, sink, len);
256
257 actual -= len;
258 }
259 }
260
261 return result;
262}
263
264static
265enum mad_flow check_message(struct mad_decoder *decoder)
266{
267 enum mad_flow result;
268 void *message = 0;
269 unsigned int size;
270
271 result = receive(decoder->async.in, &message, &size);
272
273 if (result == MAD_FLOW_CONTINUE) {
274 if (decoder->message_func == 0)
275 size = 0;
276 else {
277 result = decoder->message_func(decoder->cb_data, message, &size);
278
279 if (result == MAD_FLOW_IGNORE ||
280 result == MAD_FLOW_BREAK)
281 size = 0;
282 }
283
284 if (send(decoder->async.out, message, size) != MAD_FLOW_CONTINUE)
285 result = MAD_FLOW_BREAK;
286 }
287
288 if (message)
289 free(message);
290
291 return result;
292}
293# endif
294
295static
296enum mad_flow error_default(void *data, struct mad_stream *stream,
297 struct mad_frame *frame)
298{
299 int *bad_last_frame = data;
300
301 switch (stream->error) {
302 case MAD_ERROR_BADCRC:
303 if (*bad_last_frame)
304 mad_frame_mute(frame);
305 else
306 *bad_last_frame = 1;
307
308 return MAD_FLOW_IGNORE;
309
310 default:
311 return MAD_FLOW_CONTINUE;
312 }
313}
314
315static
316int run_sync(struct mad_decoder *decoder)
317{
318 enum mad_flow (*error_func)(void *, struct mad_stream *, struct mad_frame *);
319 void *error_data;
320 int bad_last_frame = 0;
321 struct mad_stream *stream;
322 struct mad_frame *frame;
323 struct mad_synth *synth;
324 int result = 0;
325
326 if (decoder->input_func == 0)
327 return 0;
328
329 if (decoder->error_func) {
330 error_func = decoder->error_func;
331 error_data = decoder->cb_data;
332 }
333 else {
334 error_func = error_default;
335 error_data = &bad_last_frame;
336 }
337
338 stream = &decoder->sync->stream;
339 frame = &decoder->sync->frame;
340 synth = &decoder->sync->synth;
341
342 mad_stream_init(stream);
343 mad_frame_init(frame);
344 mad_synth_init(synth);
345
346 mad_stream_options(stream, decoder->options);
347
348 do {
349 switch (decoder->input_func(decoder->cb_data, stream)) {
350 case MAD_FLOW_STOP:
351 goto done;
352 case MAD_FLOW_BREAK:
353 goto fail;
354 case MAD_FLOW_IGNORE:
355 continue;
356 case MAD_FLOW_CONTINUE:
357 break;
358 }
359
360 while (1) {
361# if defined(USE_ASYNC)
362 if (decoder->mode == MAD_DECODER_MODE_ASYNC) {
363 switch (check_message(decoder)) {
364 case MAD_FLOW_IGNORE:
365 case MAD_FLOW_CONTINUE:
366 break;
367 case MAD_FLOW_BREAK:
368 goto fail;
369 case MAD_FLOW_STOP:
370 goto done;
371 }
372 }
373# endif
374
375 if (decoder->header_func) {
376 if (mad_header_decode(&frame->header, stream) == -1) {
377 if (!MAD_RECOVERABLE(stream->error))
378 break;
379
380 switch (error_func(error_data, stream, frame)) {
381 case MAD_FLOW_STOP:
382 goto done;
383 case MAD_FLOW_BREAK:
384 goto fail;
385 case MAD_FLOW_IGNORE:
386 case MAD_FLOW_CONTINUE:
387 default:
388 continue;
389 }
390 }
391
392 switch (decoder->header_func(decoder->cb_data, &frame->header)) {
393 case MAD_FLOW_STOP:
394 goto done;
395 case MAD_FLOW_BREAK:
396 goto fail;
397 case MAD_FLOW_IGNORE:
398 continue;
399 case MAD_FLOW_CONTINUE:
400 break;
401 }
402 }
403
404 if (mad_frame_decode(frame, stream) == -1) {
405 if (!MAD_RECOVERABLE(stream->error))
406 break;
407
408 switch (error_func(error_data, stream, frame)) {
409 case MAD_FLOW_STOP:
410 goto done;
411 case MAD_FLOW_BREAK:
412 goto fail;
413 case MAD_FLOW_IGNORE:
414 break;
415 case MAD_FLOW_CONTINUE:
416 default:
417 continue;
418 }
419 }
420 else
421 bad_last_frame = 0;
422
423 if (decoder->filter_func) {
424 switch (decoder->filter_func(decoder->cb_data, stream, frame)) {
425 case MAD_FLOW_STOP:
426 goto done;
427 case MAD_FLOW_BREAK:
428 goto fail;
429 case MAD_FLOW_IGNORE:
430 continue;
431 case MAD_FLOW_CONTINUE:
432 break;
433 }
434 }
435
436 mad_synth_frame(synth, frame);
437
438 if (decoder->output_func) {
439 switch (decoder->output_func(decoder->cb_data,
440 &frame->header, &synth->pcm)) {
441 case MAD_FLOW_STOP:
442 goto done;
443 case MAD_FLOW_BREAK:
444 goto fail;
445 case MAD_FLOW_IGNORE:
446 case MAD_FLOW_CONTINUE:
447 break;
448 }
449 }
450 }
451 }
452 while (stream->error == MAD_ERROR_BUFLEN);
453
454 fail:
455 result = -1;
456
457 done:
458 mad_synth_finish(synth);
459 mad_frame_finish(frame);
460 mad_stream_finish(stream);
461
462 return result;
463}
464
465# if defined(USE_ASYNC)
466static
467int run_async(struct mad_decoder *decoder)
468{
469 pid_t pid;
470 int ptoc[2], ctop[2], flags;
471
472 if (pipe(ptoc) == -1)
473 return -1;
474
475 if (pipe(ctop) == -1) {
476 close(ptoc[0]);
477 close(ptoc[1]);
478 return -1;
479 }
480
481 flags = fcntl(ptoc[0], F_GETFL);
482 if (flags == -1 ||
483 fcntl(ptoc[0], F_SETFL, flags | O_NONBLOCK) == -1) {
484 close(ctop[0]);
485 close(ctop[1]);
486 close(ptoc[0]);
487 close(ptoc[1]);
488 return -1;
489 }
490
491 pid = fork();
492 if (pid == -1) {
493 close(ctop[0]);
494 close(ctop[1]);
495 close(ptoc[0]);
496 close(ptoc[1]);
497 return -1;
498 }
499
500 decoder->async.pid = pid;
501
502 if (pid) {
503 /* parent */
504
505 close(ptoc[0]);
506 close(ctop[1]);
507
508 decoder->async.in = ctop[0];
509 decoder->async.out = ptoc[1];
510
511 return 0;
512 }
513
514 /* child */
515
516 close(ptoc[1]);
517 close(ctop[0]);
518
519 decoder->async.in = ptoc[0];
520 decoder->async.out = ctop[1];
521
522 _exit(run_sync(decoder));
523
524 /* not reached */
525 return -1;
526}
527# endif
528
529/*
530 * NAME: decoder->run()
531 * DESCRIPTION: run the decoder thread either synchronously or asynchronously
532 */
533int mad_decoder_run(struct mad_decoder *decoder, enum mad_decoder_mode mode)
534{
535 int result;
536 int (*run)(struct mad_decoder *) = 0;
537
538 switch (decoder->mode = mode) {
539 case MAD_DECODER_MODE_SYNC:
540 run = run_sync;
541 break;
542
543 case MAD_DECODER_MODE_ASYNC:
544# if defined(USE_ASYNC)
545 run = run_async;
546# endif
547 break;
548 }
549
550 if (run == 0)
551 return -1;
552
553 decoder->sync = malloc(sizeof(*decoder->sync));
554 if (decoder->sync == 0)
555 return -1;
556
557 result = run(decoder);
558
559 free(decoder->sync);
560 decoder->sync = 0;
561
562 return result;
563}
564
565/*
566 * NAME: decoder->message()
567 * DESCRIPTION: send a message to and receive a reply from the decoder process
568 */
569int mad_decoder_message(struct mad_decoder *decoder,
570 void *message, unsigned int *len)
571{
572# if defined(USE_ASYNC)
573 if (decoder->mode != MAD_DECODER_MODE_ASYNC ||
574 send(decoder->async.out, message, *len) != MAD_FLOW_CONTINUE ||
575 receive(decoder->async.in, &message, len) != MAD_FLOW_CONTINUE)
576 return -1;
577
578 return 0;
579# else
580 return -1;
581# endif
582}