]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* all: who has seen that I have just forgot to release any buffers...
[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.22 2003/11/05 01:47: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 <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         }
323         else if( p_dec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
324         {
325             p_sys->output_format.i_format = AOUT_FMT_S16_NE;
326             p_sys->p_logtos16  = ulawtos16;
327         }
328     }
329     p_sys->output_format.i_rate = p_wf->nSamplesPerSec;
330
331     p_sys->output_format.i_physical_channels =
332     p_sys->output_format.i_original_channels = pi_channels_maps[p_wf->nChannels];
333
334     p_sys->p_aout       = NULL;
335     p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout,
336                                        &p_sys->output_format );
337     if( p_sys->p_aout_input == NULL )
338     {
339         msg_Err( p_dec, "cannot create aout" );
340         return VLC_EGENERIC;
341     }
342
343     aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
344     aout_DateSet( &p_sys->date, 0 );
345
346     return VLC_SUCCESS;
347 }
348
349 /*****************************************************************************
350  * DecoderDecode: decodes a frame
351  *****************************************************************************/
352 static int DecoderDecode( decoder_t *p_dec, block_t *p_block )
353 {
354     decoder_sys_t *p_sys = p_dec->p_sys;
355     int            i_size = p_block->i_buffer;
356     uint8_t        *p = p_block->p_buffer;
357     int            i_samples; // per channels
358
359     if( p_sys->p_wf->nBlockAlign > 0 )
360     {
361         /* Align it (it should already be aligned by demuxer) */
362         i_size -= i_size % p_sys->p_wf->nBlockAlign;
363     }
364     if( i_size < p_sys->p_wf->nBlockAlign )
365     {
366         block_Release( p_block );
367         return VLC_SUCCESS;
368     }
369     i_samples = i_size / ( ( p_sys->p_wf->wBitsPerSample + 7 ) / 8 ) /
370                 p_sys->p_wf->nChannels;
371
372     if( p_block->i_pts != 0 && p_block->i_pts != aout_DateGet( &p_sys->date ) )
373     {
374         aout_DateSet( &p_sys->date, p_block->i_pts );
375     }
376     else if( !aout_DateGet( &p_sys->date ) )
377     {
378         block_Release( p_block );
379         return VLC_SUCCESS;
380     }
381
382     while( i_samples > 0 )
383     {
384         int           i_copy = __MIN( i_samples, 1024 );
385         aout_buffer_t *out;
386
387         out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input, i_copy );
388         if( out == NULL )
389         {
390             msg_Err( p_dec, "cannot get aout buffer" );
391             block_Release( p_block );
392             return VLC_EGENERIC;
393         }
394
395         out->start_date = aout_DateGet( &p_sys->date );
396         out->end_date   = aout_DateIncrement( &p_sys->date, i_copy );
397
398         if( p_sys->p_logtos16 )
399         {
400             int16_t      *s = (int16_t*)out->p_buffer;
401             unsigned int i;
402
403             for( i = 0; i < out->i_nb_bytes / 2; i++ )
404             {
405                 *s++ = p_sys->p_logtos16[*p++];
406             }
407         }
408         else
409         {
410             memcpy( out->p_buffer, p, out->i_nb_bytes );
411
412             p += out->i_nb_bytes;
413         }
414
415         aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
416
417         i_samples -= i_copy;
418     }
419     block_Release( p_block );
420     return VLC_SUCCESS;
421 }
422
423 /*****************************************************************************
424  * DecoderEnd : faad decoder thread destruction
425  *****************************************************************************/
426 static int DecoderEnd( decoder_t *p_dec )
427 {
428     decoder_sys_t *p_sys = p_dec->p_sys;
429
430     if( p_sys->p_aout_input )
431     {
432         aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
433     }
434     free( p_sys );
435
436     return VLC_SUCCESS;
437 }
438
439 /*****************************************************************************
440  * EncoderOpen:
441  *****************************************************************************/
442 static int  EncoderOpen  ( vlc_object_t *p_this )
443 {
444     encoder_t *p_enc = (encoder_t *)p_this;
445
446     if( p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'b' ) &&
447         p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'l' ) )
448     {
449         msg_Warn( p_enc, "unhandled input format" );
450         return VLC_EGENERIC;
451     }
452
453     switch( p_enc->i_fourcc )
454     {
455         case VLC_FOURCC( 's', '1', '6', 'b' ):
456         case VLC_FOURCC( 's', '1', '6', 'l' ):
457         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
458         case VLC_FOURCC( 's', '8', ' ', ' ' ):
459 #if 0
460         -> could be easyly done with table look up
461         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
462         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
463 #endif
464             break;
465         default:
466             return VLC_EGENERIC;
467     }
468
469     p_enc->p_sys = NULL;
470     p_enc->pf_header = NULL;
471     p_enc->pf_encode_audio = EncoderEncode;
472     p_enc->pf_encode_video = NULL;
473     p_enc->i_extra_data = 0;
474     p_enc->p_extra_data = NULL;
475
476     return VLC_SUCCESS;
477 }
478
479 /*****************************************************************************
480  * EncoderClose:
481  *****************************************************************************/
482 static void EncoderClose ( vlc_object_t *p_this )
483 {
484     return;
485 }
486
487 /*****************************************************************************
488  * EncoderEncode:
489  *****************************************************************************/
490 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
491 {
492     block_t *p_block = NULL;
493     unsigned int i;
494
495     if( p_enc->i_fourcc == p_enc->format.audio.i_format )
496     {
497         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
498         {
499             memcpy( p_block->p_buffer, p_aout_buf->p_buffer, p_aout_buf->i_nb_bytes );
500         }
501     }
502     else if( p_enc->i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
503     {
504         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
505         {
506             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
507             int8_t  *p_src = (int8_t*) p_aout_buf->p_buffer;
508
509             if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
510             {
511                 p_src++;
512             }
513
514             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
515             {
516                 *p_dst++ = *p_src + 128; p_src += 2;
517             }
518         }
519     }
520     else if( p_enc->i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
521     {
522         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
523         {
524             int8_t *p_dst = (int8_t*)p_block->p_buffer;
525             int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
526
527             if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
528             {
529                 p_src++;
530             }
531
532             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
533             {
534                 *p_dst++ = *p_src; p_src += 2;
535             }
536         }
537     }
538     else
539     {
540         /* endian swapping */
541         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
542         {
543             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
544             uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
545
546             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
547             {
548                 p_dst[0] = p_src[1];
549                 p_dst[1] = p_src[0];
550
551                 p_dst += 2;
552                 p_src += 2;
553             }
554         }
555     }
556
557     if( p_block )
558     {
559         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
560         p_block->i_length = (int64_t)p_aout_buf->i_nb_samples * (int64_t)1000000 /
561                             p_enc->format.audio.i_rate;
562     }
563
564     return p_block;
565 }
566
567