2 * libmad - MPEG audio decoder library
3 * Copyright (C) 2000-2003 Underbit Technologies, Inc.
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.
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.
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
27 # ifdef HAVE_SYS_TYPES_H
28 # include <sys/types.h>
31 # ifdef HAVE_SYS_WAIT_H
32 # include <sys/wait.h>
55 * NAME: decoder->init()
56 * DESCRIPTION: initialize a decoder object with callback routines
58 void mad_decoder_init(struct mad_decoder
*decoder
, void *data
,
59 enum mad_flow (*input_func
)(void *,
61 enum mad_flow (*header_func
)(void *,
62 struct mad_header
const *),
63 enum mad_flow (*filter_func
)(void *,
64 struct mad_stream
const *,
66 enum mad_flow (*output_func
)(void *,
67 struct mad_header
const *,
69 enum mad_flow (*error_func
)(void *,
72 enum mad_flow (*message_func
)(void *,
79 decoder
->async
.pid
= 0;
80 decoder
->async
.in
= -1;
81 decoder
->async
.out
= -1;
85 decoder
->cb_data
= data
;
87 decoder
->input_func
= input_func
;
88 decoder
->header_func
= header_func
;
89 decoder
->filter_func
= filter_func
;
90 decoder
->output_func
= output_func
;
91 decoder
->error_func
= error_func
;
92 decoder
->message_func
= message_func
;
95 s32
mad_decoder_finish(struct mad_decoder
*decoder
)
97 # if defined(USE_ASYNC)
98 if (decoder
->mode
== MAD_DECODER_MODE_ASYNC
&& decoder
->async
.pid
) {
102 close(decoder
->async
.in
);
105 pid
= waitpid(decoder
->async
.pid
, &status
, 0);
106 while (pid
== -1 && errno
== EINTR
);
110 close(decoder
->async
.out
);
112 decoder
->async
.pid
= 0;
113 decoder
->async
.in
= -1;
114 decoder
->async
.out
= -1;
119 return (!WIFEXITED(status
) || WEXITSTATUS(status
)) ? -1 : 0;
126 # if defined(USE_ASYNC)
128 enum mad_flow
send_io(s32 fd
, void const *data
, size_t len
)
130 s8
const *ptr
= data
;
135 count
= write(fd
, ptr
, len
);
136 while (count
== -1 && errno
== EINTR
);
139 return MAD_FLOW_BREAK
;
145 return MAD_FLOW_CONTINUE
;
149 enum mad_flow
receive_io(s32 fd
, void *buffer
, size_t len
)
156 count
= read(fd
, ptr
, len
);
157 while (count
== -1 && errno
== EINTR
);
160 return (errno
== EAGAIN
) ? MAD_FLOW_IGNORE
: MAD_FLOW_BREAK
;
162 return MAD_FLOW_STOP
;
168 return MAD_FLOW_CONTINUE
;
172 enum mad_flow
receive_io_blocking(s32 fd
, void *buffer
, size_t len
)
175 enum mad_flow result
;
177 flags
= fcntl(fd
, F_GETFL
);
179 return MAD_FLOW_BREAK
;
181 blocking
= flags
& ~O_NONBLOCK
;
183 if (blocking
!= flags
&&
184 fcntl(fd
, F_SETFL
, blocking
) == -1)
185 return MAD_FLOW_BREAK
;
187 result
= receive_io(fd
, buffer
, len
);
189 if (flags
!= blocking
&&
190 fcntl(fd
, F_SETFL
, flags
) == -1)
191 return MAD_FLOW_BREAK
;
197 enum mad_flow
send(s32 fd
, void const *message
, u32 size
)
199 enum mad_flow result
;
203 result
= send_io(fd
, &size
, sizeof(size
));
207 if (result
== MAD_FLOW_CONTINUE
)
208 result
= send_io(fd
, message
, size
);
214 enum mad_flow
receive(s32 fd
, void **message
, u32
*size
)
216 enum mad_flow result
;
224 result
= receive_io(fd
, &actual
, sizeof(actual
));
226 /* receive message */
228 if (result
== MAD_FLOW_CONTINUE
) {
238 *message
= malloc(*size
);
240 return MAD_FLOW_BREAK
;
243 result
= receive_io_blocking(fd
, *message
, *size
);
246 /* throw away remainder of message */
248 while (actual
&& result
== MAD_FLOW_CONTINUE
) {
252 len
= actual
> sizeof(sink
) ? sizeof(sink
) : actual
;
254 result
= receive_io_blocking(fd
, sink
, len
);
264 enum mad_flow
check_message(struct mad_decoder
*decoder
)
266 enum mad_flow result
;
270 result
= receive(decoder
->async
.in
, &message
, &size
);
272 if (result
== MAD_FLOW_CONTINUE
) {
273 if (decoder
->message_func
== 0)
276 result
= decoder
->message_func(decoder
->cb_data
, message
, &size
);
278 if (result
== MAD_FLOW_IGNORE
||
279 result
== MAD_FLOW_BREAK
)
283 if (send(decoder
->async
.out
, message
, size
) != MAD_FLOW_CONTINUE
)
284 result
= MAD_FLOW_BREAK
;
295 enum mad_flow
error_default(void *data
, struct mad_stream
*stream
,
296 struct mad_frame
*frame
)
298 s32
*bad_last_frame
= data
;
300 switch (stream
->error
) {
301 case MAD_ERROR_BADCRC
:
303 mad_frame_mute(frame
);
307 return MAD_FLOW_IGNORE
;
310 return MAD_FLOW_CONTINUE
;
315 s32
run_sync(struct mad_decoder
*decoder
)
317 enum mad_flow (*error_func
)(void *, struct mad_stream
*, struct mad_frame
*);
319 s32 bad_last_frame
= 0;
320 struct mad_stream
*stream
;
321 struct mad_frame
*frame
;
322 struct mad_synth
*synth
;
325 if (decoder
->input_func
== 0)
328 if (decoder
->error_func
) {
329 error_func
= decoder
->error_func
;
330 error_data
= decoder
->cb_data
;
333 error_func
= error_default
;
334 error_data
= &bad_last_frame
;
337 stream
= &decoder
->sync
->stream
;
338 frame
= &decoder
->sync
->frame
;
339 synth
= &decoder
->sync
->synth
;
341 mad_stream_init(stream
);
342 mad_frame_init(frame
);
343 mad_synth_init(synth
);
345 mad_stream_options(stream
, decoder
->options
);
348 switch (decoder
->input_func(decoder
->cb_data
, stream
)) {
353 case MAD_FLOW_IGNORE
:
355 case MAD_FLOW_CONTINUE
:
360 # if defined(USE_ASYNC)
361 if (decoder
->mode
== MAD_DECODER_MODE_ASYNC
) {
362 switch (check_message(decoder
)) {
363 case MAD_FLOW_IGNORE
:
364 case MAD_FLOW_CONTINUE
:
374 if (decoder
->header_func
) {
375 if (mad_header_decode(&frame
->header
, stream
) == -1) {
376 if (!MAD_RECOVERABLE(stream
->error
))
379 switch (error_func(error_data
, stream
, frame
)) {
384 case MAD_FLOW_IGNORE
:
385 case MAD_FLOW_CONTINUE
:
391 switch (decoder
->header_func(decoder
->cb_data
, &frame
->header
)) {
396 case MAD_FLOW_IGNORE
:
398 case MAD_FLOW_CONTINUE
:
403 if (mad_frame_decode(frame
, stream
) == -1) {
404 if (!MAD_RECOVERABLE(stream
->error
))
407 switch (error_func(error_data
, stream
, frame
)) {
412 case MAD_FLOW_IGNORE
:
414 case MAD_FLOW_CONTINUE
:
422 if (decoder
->filter_func
) {
423 switch (decoder
->filter_func(decoder
->cb_data
, stream
, frame
)) {
428 case MAD_FLOW_IGNORE
:
430 case MAD_FLOW_CONTINUE
:
435 mad_synth_frame(synth
, frame
);
437 if (decoder
->output_func
) {
438 switch (decoder
->output_func(decoder
->cb_data
,
439 &frame
->header
, &synth
->pcm
)) {
444 case MAD_FLOW_IGNORE
:
445 case MAD_FLOW_CONTINUE
:
451 while (stream
->error
== MAD_ERROR_BUFLEN
);
457 mad_synth_finish(synth
);
458 mad_frame_finish(frame
);
459 mad_stream_finish(stream
);
464 # if defined(USE_ASYNC)
466 s32
run_async(struct mad_decoder
*decoder
)
469 s32 ptoc
[2], ctop
[2], flags
;
471 if (pipe(ptoc
) == -1)
474 if (pipe(ctop
) == -1) {
480 flags
= fcntl(ptoc
[0], F_GETFL
);
482 fcntl(ptoc
[0], F_SETFL
, flags
| O_NONBLOCK
) == -1) {
499 decoder
->async
.pid
= pid
;
507 decoder
->async
.in
= ctop
[0];
508 decoder
->async
.out
= ptoc
[1];
518 decoder
->async
.in
= ptoc
[0];
519 decoder
->async
.out
= ctop
[1];
521 _exit(run_sync(decoder
));
529 * NAME: decoder->run()
530 * DESCRIPTION: run the decoder thread either synchronously or asynchronously
532 s32
mad_decoder_run(struct mad_decoder
*decoder
, enum mad_decoder_mode mode
)
535 s32 (*run
)(struct mad_decoder
*) = 0;
537 switch (decoder
->mode
= mode
) {
538 case MAD_DECODER_MODE_SYNC
:
542 case MAD_DECODER_MODE_ASYNC
:
543 # if defined(USE_ASYNC)
552 decoder
->sync
= malloc(sizeof(*decoder
->sync
));
553 if (decoder
->sync
== 0)
556 result
= run(decoder
);
565 * NAME: decoder->message()
566 * DESCRIPTION: send a message to and receive a reply from the decoder process
568 s32
mad_decoder_message(struct mad_decoder
*decoder
,
569 void *message
, u32
*len
)
571 # if defined(USE_ASYNC)
572 if (decoder
->mode
!= MAD_DECODER_MODE_ASYNC
||
573 send(decoder
->async
.out
, message
, *len
) != MAD_FLOW_CONTINUE
||
574 receive(decoder
->async
.in
, &message
, len
) != MAD_FLOW_CONTINUE
)