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