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