diff options
Diffstat (limited to 'uisimulator/common/libmad/decoder.c')
-rw-r--r-- | uisimulator/common/libmad/decoder.c | 570 |
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 | |||
55 | void 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 | |||
92 | int 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) | ||
124 | static | ||
125 | enum 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 | |||
145 | static | ||
146 | enum 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 | |||
168 | static | ||
169 | enum 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 | |||
193 | static | ||
194 | enum 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 | |||
210 | static | ||
211 | enum 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 | |||
260 | static | ||
261 | enum 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 | |||
291 | static | ||
292 | enum 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 | |||
311 | static | ||
312 | int 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) | ||
462 | static | ||
463 | int 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 | |||
525 | int 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 | |||
557 | int 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 | } | ||