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