Adapted mad codec plugin to new aout3. Not tested yet.`
[vlc.git] / modules / codec / mad / libmad.c
1 /***************************************************************************
2              libmad.c  -  description
3                -------------------
4     Functions that are called by libmad to communicate with vlc decoder
5     infrastructure.
6
7     begin                : Mon Nov 5 2001
8     copyright            : (C) 2001 by Jean-Paul Saman
9     email                : jpsaman@wxs.nl
10  ***************************************************************************/
11
12 /***************************************************************************
13  *                                                                         *
14  *   This program is free software; you can redistribute it and/or modify  *
15  *   it under the terms of the GNU General Public License as published by  *
16  *   the Free Software Foundation; either version 2 of the License, or     *
17  *   (at your option) any later version.                                   *
18  *                                                                         *
19  ***************************************************************************/
20
21 /*****************************************************************************
22  * Preamble
23  *****************************************************************************/
24 #include <stdlib.h>                                      /* malloc(), free() */
25 #include <string.h>                                              /* strdup() */
26
27 #include <vlc/vlc.h>
28 #include <vlc/aout.h>
29 #include <vlc/decoder.h>
30
31 /*****************************************************************************
32  * Libmad includes files
33  *****************************************************************************/
34 #include <mad.h>
35 #include "decoder.h"
36 #include "libmad.h"
37
38 static void PrintFrameInfo(struct mad_header *Header);
39
40 /*****************************************************************************
41  * libmad_input: this function is called by libmad when the input buffer needs
42  * to be filled.
43  *****************************************************************************/
44 enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
45 {
46     mad_adec_thread_t *p_mad_adec = (mad_adec_thread_t *) data;
47     size_t             ReadSize, Remaining;
48     unsigned char     *ReadStart;
49
50     if ( p_mad_adec->p_fifo->b_die == 1 ) {
51         msg_Dbg( p_mad_adec->p_fifo, "libmad_input stopping libmad decoder" );
52         return MAD_FLOW_STOP;
53     }
54
55     if ( p_mad_adec->p_fifo->b_error == 1 ) {
56         msg_Warn( p_mad_adec->p_fifo, "libmad_input ignoring current audio frame" );
57         return MAD_FLOW_IGNORE;
58     }
59
60     /* libmad_stream_buffer does not consume the total buffer, it consumes only data
61      * for one frame only. So all data left in the buffer should be put back in front.
62      */
63     if ((p_libmad_stream->buffer==NULL) || (p_libmad_stream->error==MAD_ERROR_BUFLEN))
64     {
65         /* libmad does not consume all the buffer it's given. Some
66          * datas, part of a truncated frame, is left unused at the
67          * end of the buffer. Those datas must be put back at the
68          * beginning of the buffer and taken in account for
69          * refilling the buffer. This means that the input buffer
70          * must be large enough to hold a complete frame at the
71          * highest observable bit-rate (currently 448 kb/s). XXX=XXX
72          * Is 2016 bytes the size of the largest frame?
73          * (448000*(1152/32000))/8
74          */
75         if(p_libmad_stream->next_frame!=NULL)
76         {
77             Remaining=p_libmad_stream->bufend-p_libmad_stream->next_frame;
78             if( p_mad_adec->buffer != p_libmad_stream->next_frame )
79             {
80                 memcpy( p_mad_adec->buffer,
81                         p_libmad_stream->next_frame, Remaining );
82             }
83             ReadStart=p_mad_adec->buffer+Remaining;
84             ReadSize=(MAD_BUFFER_MDLEN)-Remaining;
85
86             /* Store time stamp of next frame */
87             p_mad_adec->i_current_pts = p_mad_adec->i_next_pts;
88             p_mad_adec->i_next_pts = p_mad_adec->p_fifo->p_first->i_pts;
89         }
90         else
91         {
92             ReadSize=(MAD_BUFFER_MDLEN);
93             ReadStart=p_mad_adec->buffer;
94             Remaining=0;
95             p_mad_adec->i_next_pts = 0;
96             p_mad_adec->i_current_pts = p_mad_adec->p_fifo->p_first->i_pts;
97         }
98
99         /* Fill-in the buffer. If an error occurs print a message
100          * and leave the decoding loop. If the end of stream is
101          * reached we also leave the loop but the return status is
102          * left untouched.
103          */
104         if( ReadSize > p_mad_adec->p_data->p_payload_end
105                         - p_mad_adec->p_data->p_payload_start )
106         {
107             ReadSize = p_mad_adec->p_data->p_payload_end
108                         - p_mad_adec->p_data->p_payload_start;
109             memcpy( ReadStart, p_mad_adec->p_data->p_payload_start, ReadSize );
110             NextDataPacket( p_mad_adec->p_fifo, &p_mad_adec->p_data );
111         }
112         else
113         {
114             memcpy( ReadStart, p_mad_adec->p_data->p_payload_start, ReadSize );
115             p_mad_adec->p_data->p_payload_start += ReadSize;
116         }
117
118         if ( p_mad_adec->p_fifo->b_die == 1 )
119         {
120             msg_Dbg( p_mad_adec->p_fifo, "libmad_input stopping libmad decoder" );
121             return MAD_FLOW_STOP;
122         }
123
124         if ( p_mad_adec->p_fifo->b_error == 1 )
125         {
126             msg_Warn( p_mad_adec->p_fifo, "libmad_input ignoring current audio frame" );    
127             return MAD_FLOW_IGNORE;
128         }
129
130         /* Pipe the new buffer content to libmad's stream decoder facility.
131          * Libmad never copies the buffer, but just references it. So keep it in
132          * mad_adec_thread_t structure.
133          */
134         mad_stream_buffer(p_libmad_stream,(unsigned char*) &p_mad_adec->buffer,
135                           Remaining + ReadSize);
136         p_libmad_stream->error=0;
137     }
138
139     return MAD_FLOW_CONTINUE;
140 }
141
142 /*****************************************************************************
143  * libmad_header: this function is called just after the header of a frame is
144  * decoded
145  *****************************************************************************/
146 /*
147  *enum mad_flow libmad_header(void *data, struct mad_header const *p_libmad_header)
148  *{
149  *   mad_adec_thread_t *p_mad_adec = (mad_adec_thread_t *) data;
150  *
151  *   msg_Err( p_mad_adec->p_fifo, "libmad_header samplerate %d", p_libmad_header->samplerate);
152  *
153  *   PrintFrameInfo(p_limad_mad_header)
154  *   return MAD_FLOW_CONTINUE;
155  *}
156  */
157
158 /*****************************************************************************
159  * lib_mad_filter: this function is called to filter data of a frame
160  *****************************************************************************/
161 /* enum mad_flow libmad_filter(void *data, struct mad_stream const *p_libmad_stream, struct mad_frame *p_libmad_frame)
162  * {
163  *      return MAD_FLOW_CONTINUE;
164  * }
165  */
166
167 /*****************************************************************************
168  * support routines borrowed from mpg321 (file: mad.c), which is distributed
169  * under GPL license
170  *
171  * mpg321 was written by Joe Drew <drew@debian.org>, and based upon 'plaympeg'
172  * from the smpeg sources, which was written by various people from Loki Software
173  * (http://www.lokigames.com).
174  *
175  * It also incorporates some source from mad, written by Robert Leslie
176  *****************************************************************************/
177
178 /* The following two routines and data structure are from the ever-brilliant
179      Rob Leslie.
180 */
181
182 struct audio_dither {
183     mad_fixed_t error[3];
184     mad_fixed_t random;
185 };
186
187 /*
188 * NAME:                prng()
189 * DESCRIPTION: 32-bit pseudo-random number generator
190 */
191 static inline unsigned long prng(unsigned long state)
192 {
193     return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
194 }
195
196 /*
197 * NAME:        mpg321_s24_to_s16_pcm()
198 * DESCRIPTION: generic linear sample quantize and dither routine
199 */
200 static inline signed int mpg321_s24_to_s16_pcm(unsigned int bits, mad_fixed_t sample,
201                                     struct audio_dither *dither)
202 {
203     unsigned int scalebits;
204     mad_fixed_t output, mask, random;
205
206     enum {
207         MIN = -MAD_F_ONE,
208         MAX = MAD_F_ONE - 1
209     };
210
211     /* noise shape */
212     sample += dither->error[0] - dither->error[1] + dither->error[2];
213
214     dither->error[2] = dither->error[1];
215     dither->error[1] = dither->error[0] / 2;
216
217     /* bias */
218     output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
219
220     scalebits = MAD_F_FRACBITS + 1 - bits;
221     mask = (1L << scalebits) - 1;
222
223     /* dither */
224     random    = prng(dither->random);
225     output += (random & mask) - (dither->random & mask);
226
227     dither->random = random;
228
229     /* clip */
230     if (output > MAX) {
231         output = MAX;
232
233         if (sample > MAX)
234             sample = MAX;
235     }
236     else if (output < MIN) {
237         output = MIN;
238
239         if (sample < MIN)
240             sample = MIN;
241     }
242
243     /* quantize */
244     output &= ~mask;
245
246     /* error feedback */
247     dither->error[0] = sample - output;
248
249     /* scale */
250     return output >> scalebits;
251 }
252
253 /*****************************************************************************
254  * s24_to_s16_pcm: Scale a 24 bit pcm sample to a 16 bit pcm sample.
255  *****************************************************************************/
256 static inline mad_fixed_t s24_to_s16_pcm(mad_fixed_t sample)
257 {
258   /* round */
259   sample += (1L << (MAD_F_FRACBITS - 16));
260
261   /* clip */
262   if (sample >= MAD_F_ONE)
263     sample = MAD_F_ONE - 1;
264   else if (sample < -MAD_F_ONE)
265     sample = -MAD_F_ONE;
266
267   /* quantize */
268   return sample >> (MAD_F_FRACBITS + 1 - 16);
269 }
270
271 /*****************************************************************************
272  * libmad_ouput: this function is called just after the frame is decoded
273  *****************************************************************************/
274 //enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm)
275 //{
276 //    mad_adec_thread_t *p_mad_adec= (mad_adec_thread_t *) data;
277 //    byte_t *buffer=NULL;
278 //    mad_fixed_t const *left_ch = p_libmad_pcm->samples[0], *right_ch = p_libmad_pcm->samples[1];
279 //    register int nsamples = p_libmad_pcm->length;
280 //    mad_fixed_t sample;
281 //    static struct audio_dither dither;
282 //
283 //    /* Creating the audio output fifo.
284 //     * Assume the samplerate and nr of channels from the first decoded frame is right for the entire audio track.
285 //     */
286 //    if (p_mad_adec->p_aout_fifo==NULL)
287 //    {
288 //      p_mad_adec->p_aout_fifo = aout_CreateFifo(
289 //                p_mad_adec->p_fifo,
290 //                AOUT_FIFO_PCM,              /* fifo type */
291 //                2, /*p_libmad_pcm->channels,*/     /* nr. of channels */
292 //                p_libmad_pcm->samplerate,   /* frame rate in Hz ?*/
293 //                p_libmad_pcm->length*2,     /* length of output buffer *2 channels*/
294 //                NULL  );                    /* buffer */
295 //
296 //      if ( p_mad_adec->p_aout_fifo == NULL )
297 //      {
298 //              return MAD_FLOW_BREAK;
299 //      }
300 //
301 //        msg_Dbg( p_mad_adec->p_fifo, "aout fifo created");
302 //    }
303 //
304 //    if (p_mad_adec->p_aout_fifo->i_rate != p_libmad_pcm->samplerate)
305 //    {
306 //      msg_Warn( p_mad_adec->p_fifo, "samplerate is changing from [%d] Hz "
307 //                  "to [%d] Hz, sample size [%d], error_code [%0x]",
308 //                  p_mad_adec->p_aout_fifo->i_rate, p_libmad_pcm->samplerate,
309 //                  p_libmad_pcm->length,
310 //                  p_mad_adec->libmad_decoder->sync->stream.error );
311 //      p_mad_adec->p_aout_fifo->i_rate = p_libmad_pcm->samplerate;
312 //    }
313 //
314 //    if( p_mad_adec->i_current_pts )
315 //    {
316 //        p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame]
317 //                = p_mad_adec->i_current_pts;
318 //    }
319 //    else
320 //    {
321 //        p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->i_end_frame]
322 //                = LAST_MDATE;
323 //    }
324 ////    mad_timer_add(&p_mad_adec->libmad_timer,p_libmad_header->duration);
325 //
326 //    buffer = ((byte_t *)p_mad_adec->p_aout_fifo->buffer) + (p_mad_adec->p_aout_fifo->i_end_frame * (p_libmad_pcm->length*4));
327 //
328 //    while (nsamples--)
329 //    {
330 //        switch (p_mad_adec->audio_scaling)
331 //        {
332 //          case MPG321_SCALING:
333 //               sample = mpg321_s24_to_s16_pcm(16, *left_ch++, &dither);
334 //          break;
335 //          case FAST_SCALING: /* intended fall through */
336 //          default:
337 //               sample = s24_to_s16_pcm(*left_ch++);
338 //          break;
339 //                        }
340 //
341 //        /* left audio channel */
342 //#ifndef WORDS_BIGENDIAN
343 //        *buffer++ = (byte_t) (sample >> 0);
344 //        *buffer++ = (byte_t) (sample >> 8);
345 //#else
346 //        *buffer++ = (byte_t) (sample >> 8);
347 //        *buffer++ = (byte_t) (sample >> 0);
348 //#endif
349 //              if (p_libmad_pcm->channels == 2)
350 //        {
351 //                  /* right audio channel */
352 //            switch (p_mad_adec->audio_scaling)
353 //            {
354 //              case MPG321_SCALING:
355 //                   sample = mpg321_s24_to_s16_pcm(16, *right_ch++, &dither);
356 //              break;
357 //              case FAST_SCALING: /* intended fall through */
358 //              default:
359 //                   sample = s24_to_s16_pcm(*right_ch++);
360 //              break;
361 //                        }
362 //        }
363 //        /* else reuse left_ch */
364 //#ifndef WORDS_BIGENDIAN
365 //        *buffer++ = (byte_t) (sample >> 0);
366 //        *buffer++ = (byte_t) (sample >> 8);
367 //#else
368 //        *buffer++ = (byte_t) (sample >> 8);
369 //        *buffer++ = (byte_t) (sample >> 0);
370 //#endif                                                
371 //    }
372 //
373 //    /* DEBUG */
374 //    /*
375 //    if (p_libmad_pcm->channels == 1) {
376 //       msg_Dbg( p_mad_adec->p_fifo, "libmad_output channels [%d]", p_libmad_pcm->channels);
377 //    }
378 //    */
379 //
380 //    vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock);
381 //    p_mad_adec->p_aout_fifo->i_end_frame = (p_mad_adec->p_aout_fifo->i_end_frame + 1) & AOUT_FIFO_SIZE;
382 //    vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait);
383 //    vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock);
384 //
385 //    return MAD_FLOW_CONTINUE;
386 //}
387
388 /*****************************************************************************
389  * libmad_ouput3: this function is called just after the frame is decoded
390  *****************************************************************************/
391 enum mad_flow libmad_output3(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm)
392 {
393     mad_adec_thread_t *p_mad_adec= (mad_adec_thread_t *) data;
394     aout_buffer_t * p_buffer;
395     mad_fixed_t const *left_ch = p_libmad_pcm->samples[0], *right_ch = p_libmad_pcm->samples[1];
396     register int nsamples = p_libmad_pcm->length;
397     mad_fixed_t sample;
398
399     /* Creating the audio output fifo.
400      * Assume the samplerate and nr of channels from the first decoded frame
401      * is right for the entire audio track.
402      */
403     if( (p_mad_adec->p_aout_input != NULL) &&
404         ( (p_mad_adec->output_format.i_rate != p_libmad_pcm->samplerate)
405     {
406         /* Parameters changed - this should not happen. */
407         aout_InputDelete( p_mad_adec->p_aout, p_mad_adec->p_aout_input );
408         p_mad_adec->p_aout_input = NULL;
409     }
410
411     /* Creating the audio input if not created yet. */
412     if( p_mad_adec->p_aout_input == NULL )
413     {
414         p_mad_adec->output_format.i_rate = p_libmad_pcm->samplerate;
415         /* p_mad_adec->output_format.i_channels = p_libmad_pcm->channels; */
416         p_mad_adec->p_aout_input = aout_InputNew( p_mad_adec->p_fifo,
417                                                &p_mad_adec->p_aout,
418                                                &p_mad_adec->output_format );
419
420         if ( p_mad_adec->p_aout_input == NULL )
421         {
422            p_mad_adec->p_fifo->b_error = 1;
423            return MAD_FLOW_BREAK;
424         }
425         msg_Dbg( p_mad_adec->p_fifo, "aout3 buffer created");
426     }
427
428     if (p_mad_adec->output_format->i_rate != p_libmad_pcm->samplerate)
429     {
430         msg_Warn( p_mad_adec->p_fifo, "samplerate is changing from [%d] Hz "
431                   "to [%d] Hz, sample size [%d], error_code [%0x]",
432                   p_mad_adec->p_aout_fifo->i_rate, p_libmad_pcm->samplerate,
433                   p_libmad_pcm->length,
434                   p_mad_adec->libmad_decoder->sync->stream.error );
435         p_mad_adec->output_format.i_rate = p_libmad_pcm->samplerate;
436     }
437
438     /* Set the Presentation Time Stamp */
439     p_buffer = aout_BufferNew( p_mad_adec->p_aout, p_mad_adec->p_aout_input,
440                                (p_libmad_pcm->length*4) );
441     if ( p_buffer == NULL )
442     {
443         return MAD_FLOW_BREAK;
444     }
445     /* Add accurate PTS to buffer. */
446     if ( p_mad_adec->i_current_pts )
447     {
448         p_buffer->start_date = p_mad_adec->i_current_pts;
449     }
450     else
451     {
452         p_buffer->start_date = LAST_MDATE;
453     }
454     p_mad_adec->last_date += (mtime_t)(p_libmad_pcm->length*4)
455                              / p_mad_adec->output_format.i_rate;
456     p_buffer->end_date = p_mad_adec->last_date;
457
458     /* Interleave and keep buffers in mad_fixed_t format */
459     while (nsamples--)
460     {
461         /* left audio channel */
462         sample = *left_ch++;
463 #ifndef WORDS_BIGENDIAN
464         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0);
465         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8);
466 #else
467         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8);
468         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0);
469 #endif
470         /* right audio channel */
471         if (p_libmad_pcm->channels == 2)
472         {
473            sample = *right_ch++;
474         } /* else reuse left audio channel */
475 #ifndef WORDS_BIGENDIAN
476         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0);
477         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8);
478 #else
479         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 8);
480         p_buffer->p_buffer++ = (mad_fixed_t) (sample >> 0);
481 #endif
482     }
483
484     aout_BufferPlay( p_mad_adec->p_aout, p_mad_adec->p_aout_input, p_buffer );
485
486     return MAD_FLOW_CONTINUE;
487 }
488
489 /*****************************************************************************
490  * libmad_error: this function is called when an error occurs during decoding
491  *****************************************************************************/
492 enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struct mad_frame *p_libmad_frame)
493 {
494     enum mad_flow result = MAD_FLOW_CONTINUE;
495
496     switch (p_libmad_stream->error)
497     {             
498     case MAD_ERROR_BUFLEN:                /* input buffer too small (or EOF) */
499 //X        msg_Err("libmad error: input buffer too small (or EOF)");
500         result = MAD_FLOW_CONTINUE;
501         break;
502     case MAD_ERROR_BUFPTR:                /* invalid (null) buffer pointer */
503 //X        msg_Err("libmad error: invalid (null) buffer pointer");
504         result = MAD_FLOW_STOP;
505         break;
506     case MAD_ERROR_NOMEM:                 /* not enough memory */
507 //X        msg_Err("libmad error: invalid (null) buffer pointer");
508         result = MAD_FLOW_STOP;
509         break;
510     case MAD_ERROR_LOSTSYNC:            /* lost synchronization */
511 //X        msg_Err("libmad error: lost synchronization");
512         mad_stream_sync(p_libmad_stream);
513         result = MAD_FLOW_CONTINUE;
514         break;
515     case MAD_ERROR_BADLAYER:            /* reserved header layer value */
516 //X        msg_Err("libmad error: reserved header layer value");
517         result = MAD_FLOW_CONTINUE;
518         break;
519     case MAD_ERROR_BADBITRATE:        /* forbidden bitrate value */
520 //X        msg_Err("libmad error: forbidden bitrate value");
521         result = MAD_FLOW_CONTINUE;
522         break;
523     case MAD_ERROR_BADSAMPLERATE: /* reserved sample frequency value */
524 //X        msg_Err("libmad error: reserved sample frequency value");
525         result = MAD_FLOW_CONTINUE;
526         break;
527     case MAD_ERROR_BADEMPHASIS:     /* reserved emphasis value */
528 //X        msg_Err("libmad error: reserverd emphasis value");
529         result = MAD_FLOW_CONTINUE;
530         break;
531     case MAD_ERROR_BADCRC:                /* CRC check failed */
532 //X        msg_Err("libmad error: CRC check failed");
533         result = MAD_FLOW_CONTINUE;
534         break;
535     case MAD_ERROR_BADBITALLOC:     /* forbidden bit allocation value */
536 //X        msg_Err("libmad error: forbidden bit allocation value");
537         result = MAD_FLOW_IGNORE;
538         break;
539     case MAD_ERROR_BADSCALEFACTOR:/* bad scalefactor index */
540 //X        msg_Err("libmad error: bad scalefactor index");
541         result = MAD_FLOW_CONTINUE;
542         break;
543     case MAD_ERROR_BADFRAMELEN:     /* bad frame length */
544 //X        msg_Err("libmad error: bad frame length");
545         result = MAD_FLOW_CONTINUE;
546         break;
547     case MAD_ERROR_BADBIGVALUES:    /* bad big_values count */
548 //X        msg_Err("libmad error: bad big values count");
549         result = MAD_FLOW_IGNORE;
550         break;
551     case MAD_ERROR_BADBLOCKTYPE:    /* reserved block_type */
552 //X        msg_Err("libmad error: reserverd block_type");
553         result = MAD_FLOW_IGNORE;
554         break;
555     case MAD_ERROR_BADSCFSI:            /* bad scalefactor selection info */
556 //X        msg_Err("libmad error: bad scalefactor selection info");
557         result = MAD_FLOW_CONTINUE;
558         break;
559     case MAD_ERROR_BADDATAPTR:        /* bad main_data_begin pointer */
560 //X        msg_Err("libmad error: bad main_data_begin pointer");
561         result = MAD_FLOW_STOP;
562         break;
563     case MAD_ERROR_BADPART3LEN:     /* bad audio data length */
564 //X        msg_Err("libmad error: bad audio data length");
565         result = MAD_FLOW_IGNORE;
566         break;
567     case MAD_ERROR_BADHUFFTABLE:    /* bad Huffman table select */
568 //X        msg_Err("libmad error: bad Huffman table select");
569         result = MAD_FLOW_IGNORE;
570         break;
571     case MAD_ERROR_BADHUFFDATA:     /* Huffman data overrun */
572 //X        msg_Err("libmad error: Huffman data overrun");
573         result = MAD_FLOW_IGNORE;
574         break;
575     case MAD_ERROR_BADSTEREO:         /* incompatible block_type for JS */
576 //X        msg_Err("libmad error: incompatible block_type for JS");
577         result = MAD_FLOW_IGNORE;
578         break;
579     default:
580 //X        msg_Err("libmad error: unknown error occured stopping decoder");
581         result = MAD_FLOW_STOP;
582         break;
583     }
584     
585     return (MAD_RECOVERABLE(p_libmad_stream->error)? result: MAD_FLOW_STOP);
586     //return (MAD_FLOW_CONTINUE);
587 }
588
589 /*****************************************************************************
590  * libmad_message: this function is called to send a message
591  *****************************************************************************/
592 /* enum mad_flow libmad_message(void *, void*, unsigned int*)
593  * {
594  *     return MAD_FLOW_CONTINUE;
595  * }
596  */
597
598
599
600 /****************************************************************************
601  * Print human readable informations about an audio MPEG frame.                         *
602  ****************************************************************************/
603 static void PrintFrameInfo(struct mad_header *Header)
604 {
605         const char      *Layer,
606                         *Mode,
607                         *Emphasis;
608
609         /* Convert the layer number to it's printed representation. */
610         switch(Header->layer)
611         {
612                 case MAD_LAYER_I:
613                         Layer="I";
614                         break;
615                 case MAD_LAYER_II:
616                         Layer="II";
617                         break;
618                 case MAD_LAYER_III:
619                         Layer="III";
620                         break;
621                 default:
622                         Layer="(unexpected layer value)";
623                         break;
624         }
625
626         /* Convert the audio mode to it's printed representation. */
627         switch(Header->mode)
628         {
629                 case MAD_MODE_SINGLE_CHANNEL:
630                         Mode="single channel";
631                         break;
632                 case MAD_MODE_DUAL_CHANNEL:
633                         Mode="dual channel";
634                         break;
635                 case MAD_MODE_JOINT_STEREO:
636                         Mode="joint (MS/intensity) stereo";
637                         break;
638                 case MAD_MODE_STEREO:
639                         Mode="normal LR stereo";
640                         break;
641                 default:
642                         Mode="(unexpected mode value)";
643                         break;
644         }
645
646         /* Convert the emphasis to it's printed representation. */
647         switch(Header->emphasis)
648         {
649                 case MAD_EMPHASIS_NONE:
650                         Emphasis="no";
651                         break;
652                 case MAD_EMPHASIS_50_15_US:
653                         Emphasis="50/15 us";
654                         break;
655                 case MAD_EMPHASIS_CCITT_J_17:
656                         Emphasis="CCITT J.17";
657                         break;
658                 default:
659                         Emphasis="(unexpected emphasis value)";
660                         break;
661         }
662
663 //X     msg_Err("statistics: %lu kb/s audio mpeg layer %s stream %s crc, "
664 //X                     "%s with %s emphasis at %d Hz sample rate\n",
665 //X                     Header->bitrate,Layer,
666 //X                     Header->flags&MAD_FLAG_PROTECTION?"with":"without",
667 //X                     Mode,Emphasis,Header->samplerate);
668 }