annotate src/libmad-0.15.1b/decoder.c @ 6:35e00f62c407

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