]> git.sesse.net Git - vlc/blob - plugins/mad_adec/mad_libmad.c
libmad plug-in, courtesy of Jean-Paul Saman <jpsaman@wxs.nl>.
[vlc] / plugins / mad_adec / mad_libmad.c
1 /***************************************************************************
2            mad_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
25 #include "defs.h"
26
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <string.h>                                              /* strdup() */
29
30 #include "config.h"
31 #include "common.h"                                     /* boolean_t, byte_t */
32 #include "intf_msg.h"
33 #include "threads.h"
34 #include "mtime.h"
35 #include "intf_msg.h"
36
37 #include "audio_output.h"
38
39 #include "modules.h"
40 #include "modules_export.h"
41
42 #include "stream_control.h"
43 #include "input_ext-dec.h"
44
45 #include "debug.h"
46
47 /*****************************************************************************
48  * Libmad includes files
49  *****************************************************************************/
50
51 #include <mad.h>
52 #include "mad_adec.h"
53 #include "mad_libmad.h"
54
55 /*****************************************************************************
56  * libmad_input: this function is called by libmad when the input buffer needs
57  * to be filled.
58  *****************************************************************************/
59 enum mad_flow libmad_input(void *data, struct mad_stream *p_libmad_stream)
60 {
61     mad_adec_thread_t *p_mad_adec = (mad_adec_thread_t *) data;
62     byte_t buffer[ADEC_FRAME_SIZE];
63
64     /* Store time stamp of current frame */
65     if ( DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts ) {
66          p_mad_adec->i_pts_save = DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts;
67          DECODER_FIFO_START(*p_mad_adec->p_fifo)->i_pts = 0;
68     }
69     else {
70          p_mad_adec->i_pts_save = LAST_MDATE;
71     }
72
73     GetChunk( &p_mad_adec->bit_stream, buffer, ADEC_FRAME_SIZE );
74
75     if ( p_mad_adec->p_fifo->b_die == 1 ) {
76         intf_ErrMsg( "mad_adec error: libmad_input stopping libmad decoder" );
77         return MAD_FLOW_STOP;
78     }
79
80     if ( p_mad_adec->p_fifo->b_error == 1 ) {
81         intf_ErrMsg( "mad_adec error: libmad_input ignoring current audio frame" );     
82         return MAD_FLOW_IGNORE;
83     }
84
85     /* the length meant to be in bytes */
86     mad_stream_buffer(p_libmad_stream, (unsigned char*) &buffer, ADEC_FRAME_SIZE );
87
88     return MAD_FLOW_CONTINUE;
89 }
90
91 /*****************************************************************************
92  * libmad_header: this function is called just after the header of a frame is
93  * decoded
94  *****************************************************************************/
95 enum mad_flow libmad_header(void *data, struct mad_header const *p_libmad_header)
96 {
97     mad_adec_thread_t *p_mad_adec = (mad_adec_thread_t *) data;
98
99     vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock);
100 /*
101     intf_ErrMsg( "mad_adec: libmad_header samplerate %d", p_libmad_header->samplerate);
102         intf_DbgMsg( "mad_adec: libmad_header bitrate %d", p_libmad_header->bitrate);   
103 */
104     p_mad_adec->p_aout_fifo->l_rate = p_libmad_header->samplerate;
105     vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait);
106     vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock);
107
108     return MAD_FLOW_CONTINUE;
109 }
110
111 /*****************************************************************************
112  * lib_mad_filter: this function is called to filter data of a frame
113  *****************************************************************************/
114 /* enum mad_flow libmad_filter(void *data, struct mad_stream const *p_libmad_stream, struct mad_frame *p_libmad_frame)
115  * {
116  *      return MAD_FLOW_CONTINUE;
117  * }
118  */
119
120 /*****************************************************************************
121  * support routines borrowed from mpg321 (file: mad.c), which is distributed
122  * under GPL license
123  *
124  * mpg321 was written by Joe Drew <drew@debian.org>, and based upon 'plaympeg'
125  * from the smpeg sources, which was written by various people from Loki Software
126  * (http://www.lokigames.com).
127  *
128  * It also incorporates some source from mad, written by Robert Leslie
129  *****************************************************************************/
130
131 /* The following two routines and data structure are from the ever-brilliant
132      Rob Leslie.
133 */
134
135 struct audio_dither {
136     mad_fixed_t error[3];
137     mad_fixed_t random;
138 };
139
140 /*
141 * NAME:                prng()
142 * DESCRIPTION: 32-bit pseudo-random number generator
143 */
144 static __inline__ unsigned long prng(unsigned long state)
145 {
146     return (state * 0x0019660dL + 0x3c6ef35fL) & 0xffffffffL;
147 }
148
149 /*
150 * NAME:                audio_linear_dither()
151 * DESCRIPTION: generic linear sample quantize and dither routine
152 */
153 static __inline__ signed long audio_linear_dither(unsigned int bits, mad_fixed_t sample,
154                                     struct audio_dither *dither)
155 {
156     unsigned int scalebits;
157     mad_fixed_t output, mask, random;
158
159     enum {
160         MIN = -MAD_F_ONE,
161         MAX =    MAD_F_ONE - 1
162     };
163
164     /* noise shape */
165     sample += dither->error[0] - dither->error[1] + dither->error[2];
166
167     dither->error[2] = dither->error[1];
168     dither->error[1] = dither->error[0] / 2;
169
170     /* bias */
171     output = sample + (1L << (MAD_F_FRACBITS + 1 - bits - 1));
172
173     scalebits = MAD_F_FRACBITS + 1 - bits;
174     mask = (1L << scalebits) - 1;
175
176     /* dither */
177     random    = prng(dither->random);
178     output += (random & mask) - (dither->random & mask);
179
180     dither->random = random;
181
182     /* clip */
183     if (output > MAX) {
184         output = MAX;
185
186         if (sample > MAX)
187             sample = MAX;
188     }
189     else if (output < MIN) {
190         output = MIN;
191
192         if (sample < MIN)
193             sample = MIN;
194     }
195
196     /* quantize */
197     output &= ~mask;
198
199     /* error feedback */
200     dither->error[0] = sample - output;
201
202     /* scale */
203     return output >> scalebits;
204 }
205
206 /*****************************************************************************
207  * libmad_ouput: this function is called just after the frame is decoded
208  *****************************************************************************/
209 enum mad_flow libmad_output(void *data, struct mad_header const *p_libmad_header, struct mad_pcm *p_libmad_pcm)
210 {
211     mad_adec_thread_t *p_mad_adec= (mad_adec_thread_t *) data;
212     byte_t *buffer=NULL;
213
214     mad_fixed_t const *left_ch = p_libmad_pcm->samples[0], *right_ch = p_libmad_pcm->samples[1];
215     /*
216      * 1152 because that's what mad has as a max; *4 because
217      * there are 4 distinct bytes per sample (in 2 channel case)
218      */
219     static unsigned char stream[ADEC_FRAME_SIZE];
220     register int nsamples = p_libmad_pcm->length;
221     static struct audio_dither dither;
222
223     register char * ptr = stream;
224     register signed int sample;
225
226     /* Set timestamp to synchronize audio and video decoder fifo's */
227     vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock);
228     p_mad_adec->p_aout_fifo->date[p_mad_adec->p_aout_fifo->l_end_frame] = p_mad_adec->i_pts_save;
229
230     buffer = ((byte_t *)p_mad_adec->p_aout_fifo->buffer) + (p_mad_adec->p_aout_fifo->l_end_frame * ADEC_FRAME_SIZE);
231
232     if (p_libmad_pcm->channels == 2)
233     {
234         while (nsamples--)
235         {
236             sample = (signed int) audio_linear_dither(16, *left_ch++, &dither);
237 #ifndef WORDS_BIGENDIAN
238             *ptr++ = (unsigned char) (sample >> 0);
239             *ptr++ = (unsigned char) (sample >> 8);
240 #else
241             *ptr++ = (unsigned char) (sample >> 8);
242             *ptr++ = (unsigned char) (sample >> 0);
243 #endif
244
245             sample = (signed int) audio_linear_dither(16, *right_ch++, &dither);
246 #ifndef WORDS_BIGENDIAN
247             *ptr++ = (unsigned char) (sample >> 0);
248             *ptr++ = (unsigned char) (sample >> 8);
249 #else
250             *ptr++ = (unsigned char) (sample >> 8);
251             *ptr++ = (unsigned char) (sample >> 0);
252 #endif                                          
253         }
254         buffer = memcpy(buffer,stream,p_libmad_pcm->length*4);
255         vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait);
256   }
257   else
258   {
259         while (nsamples--)
260         {
261             sample = (signed int) audio_linear_dither(16, *left_ch++, &dither);
262
263 #ifndef WORDS_BIGENDIAN
264             *ptr++ = (unsigned char) (sample >> 0);
265             *ptr++ = (unsigned char) (sample >> 8);
266 #else
267             *ptr++ = (unsigned char) (sample >> 8);
268             *ptr++ = (unsigned char) (sample >> 0);
269 #endif                                  
270         }
271         buffer = memcpy(buffer,stream,p_libmad_pcm->length*2);
272         vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait);
273     }
274     vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock);
275
276     vlc_mutex_lock (&p_mad_adec->p_aout_fifo->data_lock);
277     p_mad_adec->p_aout_fifo->l_end_frame = (p_mad_adec->p_aout_fifo->l_end_frame + 1) & AOUT_FIFO_SIZE;
278     vlc_cond_signal (&p_mad_adec->p_aout_fifo->data_wait);
279     vlc_mutex_unlock (&p_mad_adec->p_aout_fifo->data_lock);
280
281     return MAD_FLOW_CONTINUE;
282 }
283
284 /*****************************************************************************
285  * libmad_error: this function is called when an error occurs during decoding
286  *****************************************************************************/
287 enum mad_flow libmad_error(void *data, struct mad_stream *p_libmad_stream, struct mad_frame *p_libmad_frame)
288 {
289     enum mad_flow result = MAD_FLOW_CONTINUE;
290
291     switch (p_libmad_stream->error)
292     {             
293     case MAD_ERROR_BUFLEN:                /* input buffer too small (or EOF) */
294         intf_ErrMsg("libmad error: input buffer too small (or EOF)");
295         result = MAD_FLOW_CONTINUE;
296         break;
297     case MAD_ERROR_BUFPTR:                /* invalid (null) buffer pointer */
298         intf_ErrMsg("libmad error: invalid (null) buffer pointer");
299         result = MAD_FLOW_STOP;
300         break;
301     case MAD_ERROR_NOMEM:                 /* not enough memory */
302         intf_ErrMsg("libmad error: invalid (null) buffer pointer");
303         result = MAD_FLOW_STOP;
304         break;
305     case MAD_ERROR_LOSTSYNC:            /* lost synchronization */
306         intf_ErrMsg("libmad error: lost synchronization");
307         mad_stream_sync(p_libmad_stream);
308         result = MAD_FLOW_CONTINUE;
309         break;
310     case MAD_ERROR_BADLAYER:            /* reserved header layer value */
311         intf_ErrMsg("libmad error: reserved header layer value");
312         result = MAD_FLOW_CONTINUE;
313         break;
314     case MAD_ERROR_BADBITRATE:        /* forbidden bitrate value */
315         intf_ErrMsg("libmad error: forbidden bitrate value");
316         result = MAD_FLOW_CONTINUE;
317         break;
318     case MAD_ERROR_BADSAMPLERATE: /* reserved sample frequency value */
319             intf_ErrMsg("libmad error: reserved sample frequency value");
320         result = MAD_FLOW_CONTINUE;
321         break;
322     case MAD_ERROR_BADEMPHASIS:     /* reserved emphasis value */
323         intf_ErrMsg("libmad error: reserverd emphasis value");
324         result = MAD_FLOW_CONTINUE;
325         break;
326     case MAD_ERROR_BADCRC:                /* CRC check failed */
327         intf_ErrMsg("libmad error: CRC check failed");
328         result = MAD_FLOW_CONTINUE;
329         break;
330     case MAD_ERROR_BADBITALLOC:     /* forbidden bit allocation value */
331         intf_ErrMsg("libmad error: forbidden bit allocation value");
332         result = MAD_FLOW_IGNORE;
333         break;
334     case MAD_ERROR_BADSCALEFACTOR:/* bad scalefactor index */
335         intf_ErrMsg("libmad error: bad scalefactor index");
336         result = MAD_FLOW_CONTINUE;
337         break;
338     case MAD_ERROR_BADFRAMELEN:     /* bad frame length */
339         intf_ErrMsg("libmad error: bad frame length");
340         result = MAD_FLOW_CONTINUE;
341         break;
342     case MAD_ERROR_BADBIGVALUES:    /* bad big_values count */
343         intf_ErrMsg("libmad error: bad big values count");
344         result = MAD_FLOW_IGNORE;
345         break;
346     case MAD_ERROR_BADBLOCKTYPE:    /* reserved block_type */
347         intf_ErrMsg("libmad error: reserverd block_type");
348         result = MAD_FLOW_IGNORE;
349         break;
350     case MAD_ERROR_BADSCFSI:            /* bad scalefactor selection info */
351         intf_ErrMsg("libmad error: bad scalefactor selection info");
352         result = MAD_FLOW_CONTINUE;
353         break;
354     case MAD_ERROR_BADDATAPTR:        /* bad main_data_begin pointer */
355         intf_ErrMsg("libmad error: bad main_data_begin pointer");
356         result = MAD_FLOW_STOP;
357         break;
358     case MAD_ERROR_BADPART3LEN:     /* bad audio data length */
359         intf_ErrMsg("libmad error: bad audio data length");
360         result = MAD_FLOW_IGNORE;
361         break;
362     case MAD_ERROR_BADHUFFTABLE:    /* bad Huffman table select */
363         intf_ErrMsg("libmad error: bad Huffman table select");
364         result = MAD_FLOW_IGNORE;
365         break;
366     case MAD_ERROR_BADHUFFDATA:     /* Huffman data overrun */
367         intf_ErrMsg("libmad error: Huffman data overrun");
368         result = MAD_FLOW_IGNORE;
369         break;
370     case MAD_ERROR_BADSTEREO:         /* incompatible block_type for JS */
371         intf_ErrMsg("libmad error: incompatible block_type for JS");
372         result = MAD_FLOW_IGNORE;
373         break;
374     default:
375         intf_ErrMsg("libmad error: unknown error occured stopping decoder");
376         result = MAD_FLOW_STOP;
377         break;
378     }
379     
380     //return (MAD_RECOVERABLE(p_libmad_stream->error)? result: MAD_FLOW_STOP);
381     return (MAD_FLOW_CONTINUE);
382 }
383
384 /*****************************************************************************
385  * libmad_message: this function is called to send a message
386  *****************************************************************************/
387 /* enum mad_flow libmad_message(void *, void*, unsigned int*)
388  * {
389  *     return MAD_FLOW_CONTINUE;
390  * }
391  */
392
393