]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* include/vlc_common.h:
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: araw.c,v 1.18 2003/10/25 00:49:13 sam Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <vlc/vlc.h>
28 #include <vlc/aout.h>
29 #include <vlc/decoder.h>
30 #include <vlc/input.h>
31
32 #include <stdlib.h>                                      /* malloc(), free() */
33 #include <string.h>                                              /* strdup() */
34 #include "codecs.h"
35 /*****************************************************************************
36  * Local prototypes
37  *****************************************************************************/
38
39 typedef struct adec_thread_s
40 {
41     WAVEFORMATEX    *p_wf;
42
43     /* Input properties */
44     decoder_fifo_t *p_fifo;
45     int16_t        *p_logtos16;  // used with m/alaw to int16_t
46
47     /* Output properties */
48     aout_instance_t *   p_aout;       /* opaque */
49     aout_input_t *      p_aout_input; /* opaque */
50     audio_sample_format_t output_format;
51
52     audio_date_t        date;
53     mtime_t             pts;
54
55 } adec_thread_t;
56
57 static int  OpenDecoder    ( vlc_object_t * );
58
59 static int  RunDecoder     ( decoder_fifo_t * );
60 static int  InitThread     ( adec_thread_t * );
61 static void DecodeThread   ( adec_thread_t * );
62 static void EndThread      ( adec_thread_t * );
63
64 /*****************************************************************************
65  * Module descriptor
66  *****************************************************************************/
67
68 vlc_module_begin();
69     set_description( _("Pseudo Raw/Log Audio decoder") );
70     set_capability( "decoder", 50 );
71     set_callbacks( OpenDecoder, NULL );
72 vlc_module_end();
73
74
75 /*****************************************************************************
76  * OpenDecoder: probe the decoder and return score
77  *****************************************************************************
78  * Tries to launch a decoder and return score so that the interface is able
79  * to choose.
80  *****************************************************************************/
81 static int OpenDecoder( vlc_object_t *p_this )
82 {
83     decoder_t *p_dec = (decoder_t*)p_this;
84
85     switch( p_dec->p_fifo->i_fourcc )
86     {
87         case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
88         case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
89         case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
90
91         case VLC_FOURCC('a','l','a','w'):
92         case VLC_FOURCC('u','l','a','w'):
93             p_dec->pf_run = RunDecoder;
94             return VLC_SUCCESS;
95
96         default:
97             return VLC_EGENERIC;
98     }
99 }
100
101 static int pi_channels_maps[6] =
102 {
103     0,
104     AOUT_CHAN_CENTER,
105     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
106     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
107     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
108     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
109      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
110 };
111
112 static int16_t ulawtos16[256] =
113 {
114     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
115     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
116     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
117     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
118      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
119      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
120      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
121      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
122      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
123      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
124       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
125       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
126       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
127       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
128       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
129        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
130      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
131      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
132      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
133      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
134       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
135       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
136       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
137       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
138       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
139       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
140        876,    844,    812,    780,    748,    716,    684,    652,
141        620,    588,    556,    524,    492,    460,    428,    396,
142        372,    356,    340,    324,    308,    292,    276,    260,
143        244,    228,    212,    196,    180,    164,    148,    132,
144        120,    112,    104,     96,     88,     80,     72,     64,
145         56,     48,     40,     32,     24,     16,      8,      0
146 };
147
148 static int16_t alawtos16[256] =
149 {
150      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
151      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
152      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
153      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
154     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
155     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
156     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
157     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
158       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
159       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
160        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
161       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
162      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
163      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
164       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
165       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
166       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
167       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
168       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
169       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
170      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
171      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
172      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
173      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
174        344,    328,    376,    360,    280,    264,    312,    296,
175        472,    456,    504,    488,    408,    392,    440,    424,
176         88,     72,    120,    104,     24,      8,     56,     40,
177        216,    200,    248,    232,    152,    136,    184,    168,
178       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
179       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
180        688,    656,    752,    720,    560,    528,    624,    592,
181        944,    912,   1008,    976,    816,    784,    880,    848
182 };
183
184 /*****************************************************************************
185  * RunDecoder: this function is called just after the thread is created
186  *****************************************************************************/
187 static int RunDecoder( decoder_fifo_t *p_fifo )
188 {
189     adec_thread_t *p_adec;
190     int b_error;
191
192     if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
193     {
194         msg_Err( p_fifo, "out of memory" );
195         DecoderError( p_fifo );
196         return( -1 );
197     }
198     memset( p_adec, 0, sizeof( adec_thread_t ) );
199
200     p_adec->p_fifo = p_fifo;
201
202     if( InitThread( p_adec ) != 0 )
203     {
204         DecoderError( p_fifo );
205         return( -1 );
206     }
207
208     while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
209     {
210         DecodeThread( p_adec );
211     }
212
213
214     if( ( b_error = p_adec->p_fifo->b_error ) )
215     {
216         DecoderError( p_adec->p_fifo );
217     }
218
219     EndThread( p_adec );
220     if( b_error )
221     {
222         return( -1 );
223     }
224
225     return( 0 );
226 }
227
228
229 #define FREE( p ) if( p ) free( p ); p = NULL
230
231 /*****************************************************************************
232  * InitThread: initialize data before entering main loop
233  *****************************************************************************/
234 static int InitThread( adec_thread_t * p_adec )
235 {
236     if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
237         == NULL )
238     {
239         msg_Err( p_adec->p_fifo, "unknown raw format" );
240         return( -1 );
241     }
242
243     /* fixing some values */
244     if( ( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_PCM ||
245           p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )&&
246         !p_adec->p_wf->nBlockAlign )
247     {
248         p_adec->p_wf->nBlockAlign =
249             p_adec->p_wf->nChannels *
250                 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
251     }
252
253     msg_Dbg( p_adec->p_fifo,
254              "raw format: samplerate:%dHz channels:%d bits/sample:%d "
255              "blockalign:%d",
256              p_adec->p_wf->nSamplesPerSec,
257              p_adec->p_wf->nChannels,
258              p_adec->p_wf->wBitsPerSample,
259              p_adec->p_wf->nBlockAlign );
260
261     /* Initialize the thread properties */
262     p_adec->p_logtos16 = NULL;
263     if( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )
264     {
265         switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
266         {
267             case( 4 ):
268                 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
269                 break;
270             case( 8 ):
271                 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
272                 break;
273             default:
274                 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
275                 return( -1 );
276         }
277     }
278     else
279     {
280         if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
281         {
282             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
283             {
284                 case( 1 ):
285                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
286                     break;
287                 case( 2 ):
288                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
289                     break;
290                 case( 3 ):
291                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
292                     break;
293                 case( 4 ):
294                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
295                     break;
296                 default:
297                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
298                     return( -1 );
299             }
300         }
301         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
302         {
303             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
304             {
305                 case( 1 ):
306                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
307                     break;
308                 case( 2 ):
309                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
310                     break;
311                 case( 3 ):
312                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
313                     break;
314                 case( 4 ):
315                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
316                     break;
317                 default:
318                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
319                     return( -1 );
320             }
321         }
322         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
323         {
324             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
325             {
326                 case( 1 ):
327                     p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
328                     break;
329                 case( 2 ):
330                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
331                     break;
332                 case( 3 ):
333                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
334                     break;
335                 case( 4 ):
336                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
337                     break;
338                 default:
339                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
340                     return( -1 );
341             }
342         }
343         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
344         {
345             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
346             p_adec->p_logtos16  = alawtos16;
347         }
348         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
349         {
350             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
351             p_adec->p_logtos16  = ulawtos16;
352         }
353     }
354     p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
355
356     if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
357     {
358         msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
359         return( -1 );
360     }
361
362     p_adec->output_format.i_physical_channels =
363             p_adec->output_format.i_original_channels =
364             pi_channels_maps[p_adec->p_wf->nChannels];
365     p_adec->p_aout = NULL;
366     p_adec->p_aout_input = NULL;
367
368     /* **** Create a new audio output **** */
369     aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
370     p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
371                                         &p_adec->p_aout,
372                                         &p_adec->output_format );
373     if( !p_adec->p_aout_input )
374     {
375         msg_Err( p_adec->p_fifo, "cannot create aout" );
376         return( -1 );
377     }
378
379     return( 0 );
380 }
381
382 static void GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
383 {
384     int i_copy;
385     int i_count;
386
387     data_packet_t   *p_data;
388
389     i_count = 0;
390     p_data = p_pes->p_first;
391     while( p_data != NULL && i_count < i_max )
392     {
393
394         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
395                         i_max - i_count );
396
397         if( i_copy > 0 )
398         {
399             memcpy( p_buf,
400                     p_data->p_payload_start,
401                     i_copy );
402         }
403
404         p_data = p_data->p_next;
405         i_count += i_copy;
406         p_buf   += i_copy;
407     }
408
409     if( i_count < i_max )
410     {
411         memset( p_buf, 0, i_max - i_count );
412     }
413 }
414
415 /*****************************************************************************
416  * DecodeThread: decodes a frame
417  *****************************************************************************/
418 static void DecodeThread( adec_thread_t *p_adec )
419 {
420     aout_buffer_t   *p_aout_buffer;
421     int             i_samples; // per channels
422     int             i_size;
423     uint8_t         *p_data, *p;
424     pes_packet_t    *p_pes;
425
426     /* **** get samples count **** */
427     input_ExtractPES( p_adec->p_fifo, &p_pes );
428     if( !p_pes )
429     {
430         p_adec->p_fifo->b_error = 1;
431         return;
432     }
433     i_size = p_pes->i_pes_size;
434
435     if( p_adec->p_wf->nBlockAlign > 0 )
436     {
437         i_size -= i_size % p_adec->p_wf->nBlockAlign;
438     }
439     if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
440     {
441         input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
442         return;
443     }
444
445     i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
446                 p_adec->p_wf->nChannels;
447
448     p_adec->pts = p_pes->i_pts;
449
450     /* **** Now we can output these samples **** */
451
452     if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
453     {
454         aout_DateSet( &p_adec->date, p_adec->pts );
455     }
456     else if( !aout_DateGet( &p_adec->date ) )
457     {
458         return;
459     }
460
461     /* gather data */
462     p = p_data = malloc( i_size );
463     GetPESData( p_data, i_size, p_pes );
464
465     while( i_samples > 0 )
466     {
467         int i_copy;
468
469         i_copy = __MIN( i_samples, 1024 );
470         p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
471                                            p_adec->p_aout_input,
472                                            i_copy );
473         if( !p_aout_buffer )
474         {
475             msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
476             p_adec->p_fifo->b_error = 1;
477
478             free( p_data );
479             return;
480         }
481
482         p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
483         p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
484                                                       i_copy );
485
486         if( p_adec->p_logtos16 )
487         {
488             int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
489
490             unsigned int     i;
491
492             for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
493             {
494                 *s++ = p_adec->p_logtos16[*p++];
495             }
496         }
497         else
498         {
499             memcpy( p_aout_buffer->p_buffer, p,
500                     p_aout_buffer->i_nb_bytes );
501
502             p += p_aout_buffer->i_nb_bytes;
503         }
504
505         aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
506
507         i_samples -= i_copy;
508     }
509
510     free( p_data );
511     input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
512 }
513
514 /*****************************************************************************
515  * EndThread : faad decoder thread destruction
516  *****************************************************************************/
517 static void EndThread (adec_thread_t *p_adec)
518 {
519     if( p_adec->p_aout_input )
520     {
521         aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
522     }
523
524     msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );
525
526     free( p_adec );
527 }