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