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