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