~ubuntu-branches/ubuntu/feisty/avidemux/feisty

« back to all changes in this revision

Viewing changes to avidemux/ADM_libMad/decoder.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel T Chen
  • Date: 2006-12-15 17:13:20 UTC
  • mfrom: (1.1.6 upstream)
  • Revision ID: james.westby@ubuntu.com-20061215171320-w79pvpehxx2fr217
Tags: 1:2.3.0-0.0ubuntu1
* Merge from debian-multimedia.org, remaining Ubuntu change:
  - desktop file,
  - no support for ccache and make -j.
* Closes Ubuntu: #69614.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
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: decoder.c,v 1.22 2004/01/23 09:41:32 rob Exp $
 
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
 */
 
59
void 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
 
 
96
int 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)
 
128
static
 
129
enum 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
 
 
149
static
 
150
enum 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
 
 
172
static
 
173
enum 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
 
 
197
static
 
198
enum 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
 
 
214
static
 
215
enum 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
 
 
264
static
 
265
enum 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
 
 
295
static
 
296
enum 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
 
 
315
static
 
316
int 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)
 
466
static
 
467
int 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
 */
 
533
int 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
 */
 
569
int 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
}