]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
b0ee2eccb1c33327ee6ab436279f81fdcf102945
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2003 VLC authors and VideoLAN
5  * $Id$
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify it
10  * under the terms of the GNU Lesser General Public License as published by
11  * the Free Software Foundation; either version 2.1 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 Lesser General Public License for more details.
18  *
19  * You should have received a copy of the GNU Lesser General Public License
20  * along with this program; if not, write to the Free Software Foundation,
21  * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
30
31 #include <assert.h>
32
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_aout.h>
37
38 /*****************************************************************************
39  * Module descriptor
40  *****************************************************************************/
41 static int  DecoderOpen ( vlc_object_t * );
42 static void DecoderClose( vlc_object_t * );
43
44 #ifdef ENABLE_SOUT
45 static int  EncoderOpen ( vlc_object_t * );
46 #endif
47
48 vlc_module_begin ()
49     /* audio decoder module */
50     set_description( N_("Raw/Log Audio decoder") )
51     set_capability( "decoder", 100 )
52     set_category( CAT_INPUT )
53     set_subcategory( SUBCAT_INPUT_ACODEC )
54     set_callbacks( DecoderOpen, DecoderClose )
55
56 #ifdef ENABLE_SOUT
57     /* audio encoder submodule */
58     add_submodule ()
59     set_description( N_("Raw audio encoder") )
60     set_capability( "encoder", 150 )
61     set_callbacks( EncoderOpen, NULL )
62 #endif
63 vlc_module_end ()
64
65 /*****************************************************************************
66  * Local prototypes
67  *****************************************************************************/
68 static block_t *DecodeBlock( decoder_t *, block_t ** );
69
70 struct decoder_sys_t
71 {
72     void (*decode) (void *, const uint8_t *, unsigned);
73     size_t framebits;
74     date_t end_date;
75 };
76
77 static const uint16_t pi_channels_maps[] =
78 {
79     0,
80     AOUT_CHAN_CENTER, AOUT_CHANS_2_0, AOUT_CHANS_3_0,
81     AOUT_CHANS_4_0,   AOUT_CHANS_5_0, AOUT_CHANS_5_1,
82     AOUT_CHANS_7_0,   AOUT_CHANS_7_1, AOUT_CHANS_8_1,
83 };
84
85 static void S8Decode( void *, const uint8_t *, unsigned );
86 static void U16BDecode( void *, const uint8_t *, unsigned );
87 static void U16LDecode( void *, const uint8_t *, unsigned );
88 static void S16IDecode( void *, const uint8_t *, unsigned );
89 static void S20BDecode( void *, const uint8_t *, unsigned );
90 static void U32BDecode( void *, const uint8_t *, unsigned );
91 static void U32LDecode( void *, const uint8_t *, unsigned );
92 static void Swap32Decode( void *, const uint8_t *, unsigned );
93 static void Swap64Decode( void *, const uint8_t *, unsigned );
94 static void DAT12Decode( void *, const uint8_t *, unsigned );
95
96 /*****************************************************************************
97  * DecoderOpen: probe the decoder and return score
98  *****************************************************************************/
99 static int DecoderOpen( vlc_object_t *p_this )
100 {
101     decoder_t *p_dec = (decoder_t*)p_this;
102     vlc_fourcc_t format = p_dec->fmt_in.i_codec;
103
104     switch( p_dec->fmt_in.i_codec )
105     {
106     case VLC_FOURCC('a','r','a','w'):
107     case VLC_FOURCC('p','c','m',' '):
108     case VLC_FOURCC('a','f','l','t'):
109     /* _signed_ big endian samples (mov) */
110     case VLC_FOURCC('t','w','o','s'):
111     /* _signed_ little endian samples (mov) */
112     case VLC_FOURCC('s','o','w','t'):
113         format =
114             vlc_fourcc_GetCodecAudio( p_dec->fmt_in.i_codec,
115                                       p_dec->fmt_in.audio.i_bitspersample );
116         if( !format )
117         {
118             msg_Err( p_dec, "bad parameters(bits/sample)" );
119             return VLC_EGENERIC;
120         }
121         break;
122     }
123
124     void (*decode) (void *, const uint8_t *, unsigned) = NULL;
125     uint_fast8_t bits;
126
127     switch( format )
128     {
129 #ifdef WORDS_BIGENDIAN
130     case VLC_CODEC_F64L:
131 #else
132     case VLC_CODEC_F64B:
133 #endif
134         format = VLC_CODEC_FL64;
135         decode = Swap64Decode;
136     case VLC_CODEC_FL64:
137         bits = 64;
138         break;
139 #ifdef WORDS_BIGENDIAN
140     case VLC_CODEC_F32L:
141 #else
142     case VLC_CODEC_F32B:
143 #endif
144         format = VLC_CODEC_FL32;
145         decode = Swap32Decode;
146     case VLC_CODEC_FL32:
147         bits = 32;
148         break;
149     case VLC_CODEC_U32B:
150         format = VLC_CODEC_S32N;
151         decode = U32BDecode;
152         bits = 32;
153         break;
154     case VLC_CODEC_U32L:
155         format = VLC_CODEC_S32N;
156         decode = U32LDecode;
157         bits = 32;
158         break;
159     case VLC_CODEC_S32I:
160         format = VLC_CODEC_S32N;
161         decode = Swap32Decode;
162      case VLC_CODEC_S32N:
163         bits = 32;
164         break;
165     case VLC_CODEC_S24L:
166     case VLC_CODEC_S24B:
167         bits = 24;
168         break;
169     case VLC_CODEC_S20B:
170         format = VLC_CODEC_S32N;
171         decode = S20BDecode;
172         bits = 20;
173         break;
174     case VLC_CODEC_U16B:
175         format = VLC_CODEC_S16N;
176         decode = U16BDecode;
177         bits = 16;
178         break;
179     case VLC_CODEC_U16L:
180         format = VLC_CODEC_S16N;
181         decode = U16LDecode;
182         bits = 16;
183         break;
184     case VLC_CODEC_S16I:
185         format = VLC_CODEC_S16N;
186         decode = S16IDecode;
187     case VLC_CODEC_S16N:
188         bits = 16;
189         break;
190     case VLC_CODEC_DAT12:
191         format = VLC_CODEC_S16N;
192         decode = DAT12Decode;
193         bits = 12;
194         break;
195     case VLC_CODEC_S8:
196         decode = S8Decode;
197         format = VLC_CODEC_U8;
198     case VLC_CODEC_U8:
199         bits = 8;
200         break;
201     default:
202         return VLC_EGENERIC;
203     }
204
205     if( p_dec->fmt_in.audio.i_channels <= 0 ||
206         p_dec->fmt_in.audio.i_channels > AOUT_CHAN_MAX )
207     {
208         msg_Err( p_dec, "bad channels count (1-9): %i",
209                  p_dec->fmt_in.audio.i_channels );
210         return VLC_EGENERIC;
211     }
212
213     if( p_dec->fmt_in.audio.i_rate <= 0 )
214     {
215         msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
216         return VLC_EGENERIC;
217     }
218
219     msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
220              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
221              p_dec->fmt_in.audio.i_bitspersample );
222
223     /* Allocate the memory needed to store the decoder's structure */
224     decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
225     if( unlikely(p_sys == NULL) )
226         return VLC_ENOMEM;
227
228     /* Set output properties */
229     p_dec->fmt_out.i_cat = AUDIO_ES;
230     p_dec->fmt_out.i_codec = format;
231     p_dec->fmt_out.audio.i_format = format;
232     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
233     if( p_dec->fmt_in.audio.i_physical_channels )
234         p_dec->fmt_out.audio.i_physical_channels =
235                                        p_dec->fmt_in.audio.i_physical_channels;
236     else
237         p_dec->fmt_out.audio.i_physical_channels =
238                               pi_channels_maps[p_dec->fmt_in.audio.i_channels];
239     if( p_dec->fmt_in.audio.i_original_channels )
240         p_dec->fmt_out.audio.i_original_channels =
241                                        p_dec->fmt_in.audio.i_original_channels;
242     else
243         p_dec->fmt_out.audio.i_original_channels =
244                                       p_dec->fmt_out.audio.i_physical_channels;
245     aout_FormatPrepare( &p_dec->fmt_out.audio );
246
247     p_sys->decode = decode;
248     p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
249     assert( p_sys->framebits );
250
251     date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
252     date_Set( &p_sys->end_date, 0 );
253
254     p_dec->pf_decode_audio = DecodeBlock;
255     p_dec->p_sys = p_sys;
256
257     return VLC_SUCCESS;
258 }
259
260 /****************************************************************************
261  * DecodeBlock: the whole thing
262  ****************************************************************************
263  * This function must be fed with whole samples (see nBlockAlign).
264  ****************************************************************************/
265 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
266 {
267     decoder_sys_t *p_sys = p_dec->p_sys;
268
269     if( !pp_block || !*pp_block ) return NULL;
270
271     block_t *p_block = *pp_block;
272
273     if( p_block->i_pts > VLC_TS_INVALID &&
274         p_block->i_pts != date_Get( &p_sys->end_date ) )
275     {
276         date_Set( &p_sys->end_date, p_block->i_pts );
277     }
278     else if( !date_Get( &p_sys->end_date ) )
279     {
280         /* We've just started the stream, wait for the first PTS. */
281         block_Release( p_block );
282         return NULL;
283     }
284
285     /* Don't re-use the same pts twice */
286     p_block->i_pts = VLC_TS_INVALID;
287
288     unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
289     if( samples == 0 )
290     {
291         block_Release( p_block );
292         return NULL;
293     }
294
295     /* Create chunks of max 1024 samples */
296     if( samples > 1024 ) samples = 1024;
297
298     block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
299     if( p_out == NULL )
300     {
301         block_Release( p_block );
302         return NULL;
303     }
304
305     p_out->i_pts = date_Get( &p_sys->end_date );
306     p_out->i_length = date_Increment( &p_sys->end_date, samples )
307                       - p_out->i_pts;
308
309     if( p_sys->decode != NULL )
310         p_sys->decode( p_out->p_buffer, p_block->p_buffer,
311                        samples * p_dec->fmt_in.audio.i_channels );
312     else
313         memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_buffer );
314
315     samples = (samples * p_sys->framebits) / 8;
316     p_block->p_buffer += samples;
317     p_block->i_buffer -= samples;
318
319     return p_out;
320 }
321
322 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
323 {
324     uint8_t *out = outp;
325
326     for( size_t i = 0; i < samples; i++ )
327         out[i] = in[i] ^ 0x80;
328 }
329
330 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
331 {
332     uint16_t *out = outp;
333
334     for( size_t i = 0; i < samples; i++ )
335     {
336         *(out++) = GetWBE( in ) - 0x8000;
337         in += 2;
338     }
339 }
340
341 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
342 {
343     uint16_t *out = outp;
344
345     for( size_t i = 0; i < samples; i++ )
346     {
347         *(out++) = GetWLE( in ) - 0x8000;
348         in += 2;
349     }
350 }
351
352 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
353 {
354     swab( in, out, samples * 2 );
355 }
356
357 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
358 {
359     int32_t *out = outp;
360
361     while( samples >= 2 )
362     {
363         uint32_t dw = U32_AT(in);
364         in += 4;
365         *(out++) = dw & ~0xFFF;
366         *(out++) = (dw << 20) | (*in << 12);
367         in++;
368         samples -= 2;
369     }
370
371     /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
372     if( samples )
373         *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
374 }
375
376 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
377 {
378     uint32_t *out = outp;
379
380     for( size_t i = 0; i < samples; i++ )
381     {
382         *(out++) = GetDWBE( in ) - 0x80000000;
383         in += 4;
384     }
385 }
386
387 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
388 {
389     uint32_t *out = outp;
390
391     for( size_t i = 0; i < samples; i++ )
392     {
393         *(out++) = GetDWLE( in ) - 0x80000000;
394         in += 4;
395     }
396 }
397
398 static void Swap32Decode( void *outp, const uint8_t *in, unsigned samples )
399 {
400     int32_t *out = outp;
401
402     for( size_t i = 0; i < samples; i++ )
403     {
404 #ifdef WORDS_BIGENDIAN
405         *(out++) = GetDWLE( in );
406 #else
407         *(out++) = GetDWBE( in );
408 #endif
409         in += 4;
410     }
411 }
412
413 static void Swap64Decode( void *outp, const uint8_t *in, unsigned samples )
414 {
415     int64_t *out = outp;
416
417     for( size_t i = 0; i < samples; i++ )
418     {
419 #ifdef WORDS_BIGENDIAN
420         *(out++) = GetQWLE( in );
421 #else
422         *(out++) = GetQWBE( in );
423 #endif
424         in += 8;
425     }
426 }
427
428 static int16_t dat12tos16( uint16_t y )
429 {
430     static const uint16_t diff[16] = {
431        0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
432        0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000 };
433     static const uint8_t shift[16] = {
434         0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0 };
435
436     int d = y >> 8;
437     return (y - diff[d]) << shift[d];
438 }
439
440 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
441 {
442     int32_t *out = outp;
443
444     while( samples >= 2 )
445     {
446         *(out++) = dat12tos16(U16_AT(in) >> 4);
447         *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
448         in += 3;
449         samples -= 2;
450     }
451
452     if( samples )
453         *(out++) = dat12tos16(U16_AT(in) >> 4);
454 }
455
456 /*****************************************************************************
457  * DecoderClose: decoder destruction
458  *****************************************************************************/
459 static void DecoderClose( vlc_object_t *p_this )
460 {
461     decoder_t *p_dec = (decoder_t *)p_this;
462
463     free( p_dec->p_sys );
464 }
465
466 #ifdef ENABLE_SOUT
467 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
468  * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
469  * since decoded audio blocks must always be aligned. */
470
471 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
472 {
473     const uint16_t *in = (const uint16_t *)inp;
474     uint16_t *out = outp;
475
476     for( size_t i = 0; i < samples; i++ )
477         *(out++) =  bswap16( *(in++) + 0x8000 );
478 }
479
480 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
481 {
482     const uint16_t *in = (const uint16_t *)inp;
483     uint16_t *out = outp;
484
485     for( size_t i = 0; i < samples; i++ )
486         *(out++) =  *(in++) + 0x8000;
487 }
488
489 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
490 {
491     const uint32_t *in = (const uint32_t *)inp;
492     uint32_t *out = outp;
493
494     for( size_t i = 0; i < samples; i++ )
495         *(out++) =  bswap32( *(in++) + 0x80000000 );
496 }
497
498 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
499 {
500     const uint32_t *in = (const uint32_t *)inp;
501     uint32_t *out = outp;
502
503     for( size_t i = 0; i < samples; i++ )
504         *(out++) =  *(in++) + 0x80000000;
505 }
506
507 static void Swap32Encode( void *outp, const uint8_t *inp, unsigned samples )
508 {
509     const int32_t *in = (const int32_t *)inp;
510     int32_t *out = outp;
511
512     for( size_t i = 0; i < samples; i++ )
513         *(out++) = bswap32( *(in++) );
514 }
515
516 static void Swap64Encode( void *outp, const uint8_t *inp, unsigned samples )
517 {
518     const int64_t *in = (const int64_t *)inp;
519     int64_t *out = outp;
520
521     for( size_t i = 0; i < samples; i++ )
522         *(out++) = bswap64( *(in++) );
523 }
524
525 static block_t *Encode( encoder_t *enc, block_t *in )
526 {
527     if( in == NULL )
528         return NULL;
529
530     block_t *out = block_Alloc( in->i_nb_samples
531                                 * enc->fmt_out.audio.i_bytes_per_frame );
532     if( unlikely(out == NULL) )
533         return NULL;
534
535     out->i_flags      = in->i_flags;
536     out->i_nb_samples = in->i_nb_samples;
537     out->i_dts        = in->i_dts;
538     out->i_pts        = in->i_pts;
539     out->i_length     = in->i_length;
540     out->i_nb_samples = in->i_nb_samples;
541
542     void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
543     if( encode != NULL )
544         encode( out->p_buffer, in->p_buffer, in->i_nb_samples
545                                              * enc->fmt_out.audio.i_channels );
546     else
547         memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
548     return out;
549 }
550
551 /**
552  * Probes the PCM audio encoder.
553  */
554 static int EncoderOpen( vlc_object_t *p_this )
555 {
556     encoder_t *p_enc = (encoder_t *)p_this;
557     void (*encode)(void *, const uint8_t *, unsigned) = NULL;
558
559     switch( p_enc->fmt_out.i_codec )
560     {
561     case VLC_CODEC_S8:
562         encode = S8Decode;
563     case VLC_CODEC_U8:
564         p_enc->fmt_in.i_codec = VLC_CODEC_U8;
565         p_enc->fmt_out.audio.i_bitspersample = 8;
566         break;
567     case VLC_CODEC_U16I:
568         encode = U16IEncode;
569         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
570         p_enc->fmt_out.audio.i_bitspersample = 16;
571         break;
572     case VLC_CODEC_U16N:
573         encode = U16NEncode;
574         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
575         p_enc->fmt_out.audio.i_bitspersample = 16;
576         break;
577     case VLC_CODEC_S16I:
578         encode = S16IDecode;
579     case VLC_CODEC_S16N:
580         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
581         p_enc->fmt_out.audio.i_bitspersample = 16;
582         break;
583     case VLC_CODEC_U24L:
584     case VLC_CODEC_U24B:
585     case VLC_CODEC_S24L:
586     case VLC_CODEC_S24B:
587         p_enc->fmt_out.audio.i_bitspersample = 24;
588         break;
589     case VLC_CODEC_U32I:
590         encode = U32IEncode;
591         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
592         p_enc->fmt_out.audio.i_bitspersample = 32;
593         break;
594     case VLC_CODEC_U32N:
595         encode = U32NEncode;
596         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
597         p_enc->fmt_out.audio.i_bitspersample = 32;
598         break;
599     case VLC_CODEC_S32I:
600         encode = Swap32Encode;
601     case VLC_CODEC_S32N:
602         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
603         p_enc->fmt_out.audio.i_bitspersample = 32;
604         break;
605 #ifdef WORDS_BIGENDIAN
606     case VLC_CODEC_F32L:
607 #else
608     case VLC_CODEC_F32B:
609 #endif
610         encode = Swap32Encode;
611     case VLC_CODEC_FL32:
612         p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
613         p_enc->fmt_out.audio.i_bitspersample = 32;
614         break;
615 #ifdef WORDS_BIGENDIAN
616     case VLC_CODEC_F64L:
617 #else
618     case VLC_CODEC_F64B:
619 #endif
620         encode = Swap64Encode;
621     case VLC_CODEC_FL64:
622         p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
623         p_enc->fmt_out.audio.i_bitspersample = 64;
624         break;
625     default:
626         return VLC_EGENERIC;
627     }
628
629     p_enc->p_sys = (void *)encode;
630     p_enc->pf_encode_audio = Encode;
631     p_enc->fmt_out.audio.i_bytes_per_frame =
632         (p_enc->fmt_out.audio.i_bitspersample / 8) *
633         p_enc->fmt_in.audio.i_channels;
634     p_enc->fmt_out.i_bitrate =
635         p_enc->fmt_in.audio.i_channels *
636         p_enc->fmt_in.audio.i_rate *
637         p_enc->fmt_out.audio.i_bitspersample;
638
639     msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
640              p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
641              p_enc->fmt_out.audio.i_bitspersample );
642
643     return VLC_SUCCESS;
644 }
645 #endif /* ENABLE_SOUT */