]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
Add support for font height as a percentage of the video height
[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 U24BDecode( void *, const uint8_t *, unsigned );
91 static void U24LDecode( void *, const uint8_t *, unsigned );
92 static void S24BDecode( void *, const uint8_t *, unsigned );
93 static void S24LDecode( void *, const uint8_t *, unsigned );
94 static void S24B32Decode( void *, const uint8_t *, unsigned );
95 static void S24L32Decode( void *, const uint8_t *, unsigned );
96 static void U32BDecode( void *, const uint8_t *, unsigned );
97 static void U32LDecode( void *, const uint8_t *, unsigned );
98 static void S32IDecode( void *, const uint8_t *, unsigned );
99 static void F32IDecode( void *, const uint8_t *, unsigned );
100 static void F64IDecode( void *, const uint8_t *, unsigned );
101 static void DAT12Decode( void *, const uint8_t *, unsigned );
102
103 /*****************************************************************************
104  * DecoderOpen: probe the decoder and return score
105  *****************************************************************************/
106 static int DecoderOpen( vlc_object_t *p_this )
107 {
108     decoder_t *p_dec = (decoder_t*)p_this;
109     vlc_fourcc_t format = p_dec->fmt_in.i_codec;
110
111     switch( p_dec->fmt_in.i_codec )
112     {
113     case VLC_FOURCC('a','r','a','w'):
114     case VLC_FOURCC('p','c','m',' '):
115     case VLC_FOURCC('a','f','l','t'):
116     /* _signed_ big endian samples (mov) */
117     case VLC_FOURCC('t','w','o','s'):
118     /* _signed_ little endian samples (mov) */
119     case VLC_FOURCC('s','o','w','t'):
120         format =
121             vlc_fourcc_GetCodecAudio( p_dec->fmt_in.i_codec,
122                                       p_dec->fmt_in.audio.i_bitspersample );
123         if( !format )
124         {
125             msg_Err( p_dec, "bad parameters(bits/sample)" );
126             return VLC_EGENERIC;
127         }
128         break;
129     }
130
131     void (*decode) (void *, const uint8_t *, unsigned) = NULL;
132     uint_fast8_t bits;
133
134     switch( format )
135     {
136 #ifdef WORDS_BIGENDIAN
137     case VLC_CODEC_F64L:
138 #else
139     case VLC_CODEC_F64B:
140 #endif
141         format = VLC_CODEC_FL64;
142         decode = F64IDecode;
143     case VLC_CODEC_FL64:
144         bits = 64;
145         break;
146 #ifdef WORDS_BIGENDIAN
147     case VLC_CODEC_F32L:
148 #else
149     case VLC_CODEC_F32B:
150 #endif
151         format = VLC_CODEC_FL32;
152         decode = F32IDecode;
153     case VLC_CODEC_FL32:
154         bits = 32;
155         break;
156     case VLC_CODEC_U32B:
157         format = VLC_CODEC_S32N;
158         decode = U32BDecode;
159         bits = 32;
160         break;
161     case VLC_CODEC_U32L:
162         format = VLC_CODEC_S32N;
163         decode = U32LDecode;
164         bits = 32;
165         break;
166     case VLC_CODEC_S32I:
167         format = VLC_CODEC_S32N;
168         decode = S32IDecode;
169     case VLC_CODEC_S32N:
170         bits = 32;
171         break;
172     case VLC_CODEC_S24B32:
173         format = VLC_CODEC_S32N;
174         decode = S24B32Decode;
175         bits = 32;
176         break;
177     case VLC_CODEC_S24L32:
178         format = VLC_CODEC_S32N;
179         decode = S24L32Decode;
180         bits = 32;
181         break;
182     case VLC_CODEC_U24B:
183         format = VLC_CODEC_S32N;
184         decode = U24BDecode;
185         bits = 24;
186         break;
187     case VLC_CODEC_U24L:
188         format = VLC_CODEC_S32N;
189         decode = U24LDecode;
190         bits = 24;
191         break;
192     case VLC_CODEC_S24B:
193         format = VLC_CODEC_S32N;
194         decode = S24BDecode;
195         bits = 24;
196         break;
197     case VLC_CODEC_S24L:
198         format = VLC_CODEC_S32N;
199         decode = S24LDecode;
200         bits = 24;
201         break;
202     case VLC_CODEC_S20B:
203         format = VLC_CODEC_S32N;
204         decode = S20BDecode;
205         bits = 20;
206         break;
207     case VLC_CODEC_U16B:
208         format = VLC_CODEC_S16N;
209         decode = U16BDecode;
210         bits = 16;
211         break;
212     case VLC_CODEC_U16L:
213         format = VLC_CODEC_S16N;
214         decode = U16LDecode;
215         bits = 16;
216         break;
217     case VLC_CODEC_S16I:
218         format = VLC_CODEC_S16N;
219         decode = S16IDecode;
220     case VLC_CODEC_S16N:
221         bits = 16;
222         break;
223     case VLC_CODEC_DAT12:
224         format = VLC_CODEC_S16N;
225         decode = DAT12Decode;
226         bits = 12;
227         break;
228     case VLC_CODEC_S8:
229         decode = S8Decode;
230         format = VLC_CODEC_U8;
231     case VLC_CODEC_U8:
232         bits = 8;
233         break;
234     default:
235         return VLC_EGENERIC;
236     }
237
238     if( p_dec->fmt_in.audio.i_channels <= 0 ||
239         p_dec->fmt_in.audio.i_channels > AOUT_CHAN_MAX )
240     {
241         msg_Err( p_dec, "bad channels count (1-9): %i",
242                  p_dec->fmt_in.audio.i_channels );
243         return VLC_EGENERIC;
244     }
245
246     if( p_dec->fmt_in.audio.i_rate <= 0 )
247     {
248         msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
249         return VLC_EGENERIC;
250     }
251
252     msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
253              p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
254              p_dec->fmt_in.audio.i_bitspersample );
255
256     /* Allocate the memory needed to store the decoder's structure */
257     decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
258     if( unlikely(p_sys == NULL) )
259         return VLC_ENOMEM;
260
261     /* Set output properties */
262     p_dec->fmt_out.i_cat = AUDIO_ES;
263     p_dec->fmt_out.i_codec = format;
264     p_dec->fmt_out.audio.i_format = format;
265     p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
266     if( p_dec->fmt_in.audio.i_physical_channels )
267         p_dec->fmt_out.audio.i_physical_channels =
268                                        p_dec->fmt_in.audio.i_physical_channels;
269     else
270         p_dec->fmt_out.audio.i_physical_channels =
271                               pi_channels_maps[p_dec->fmt_in.audio.i_channels];
272     if( p_dec->fmt_in.audio.i_original_channels )
273         p_dec->fmt_out.audio.i_original_channels =
274                                        p_dec->fmt_in.audio.i_original_channels;
275     else
276         p_dec->fmt_out.audio.i_original_channels =
277                                       p_dec->fmt_out.audio.i_physical_channels;
278     aout_FormatPrepare( &p_dec->fmt_out.audio );
279
280     p_sys->decode = decode;
281     p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
282     assert( p_sys->framebits );
283
284     date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
285     date_Set( &p_sys->end_date, 0 );
286
287     p_dec->pf_decode_audio = DecodeBlock;
288     p_dec->p_sys = p_sys;
289
290     return VLC_SUCCESS;
291 }
292
293 /****************************************************************************
294  * DecodeBlock: the whole thing
295  ****************************************************************************
296  * This function must be fed with whole samples (see nBlockAlign).
297  ****************************************************************************/
298 static block_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
299 {
300     decoder_sys_t *p_sys = p_dec->p_sys;
301
302     if( !pp_block || !*pp_block ) return NULL;
303
304     block_t *p_block = *pp_block;
305
306     if( p_block->i_pts > VLC_TS_INVALID &&
307         p_block->i_pts != date_Get( &p_sys->end_date ) )
308     {
309         date_Set( &p_sys->end_date, p_block->i_pts );
310     }
311     else if( !date_Get( &p_sys->end_date ) )
312     {
313         /* We've just started the stream, wait for the first PTS. */
314         block_Release( p_block );
315         return NULL;
316     }
317
318     /* Don't re-use the same pts twice */
319     p_block->i_pts = VLC_TS_INVALID;
320
321     unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
322     if( samples == 0 )
323     {
324         block_Release( p_block );
325         return NULL;
326     }
327
328     /* Create chunks of max 1024 samples */
329     if( samples > 1024 ) samples = 1024;
330
331     block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
332     if( p_out == NULL )
333     {
334         block_Release( p_block );
335         return NULL;
336     }
337
338     p_out->i_pts = date_Get( &p_sys->end_date );
339     p_out->i_length = date_Increment( &p_sys->end_date, samples )
340                       - p_out->i_pts;
341
342     if( p_sys->decode != NULL )
343         p_sys->decode( p_out->p_buffer, p_block->p_buffer,
344                        samples * p_dec->fmt_in.audio.i_channels );
345     else
346         memcpy( p_out->p_buffer, p_block->p_buffer, p_out->i_buffer );
347
348     samples = (samples * p_sys->framebits) / 8;
349     p_block->p_buffer += samples;
350     p_block->i_buffer -= samples;
351
352     return p_out;
353 }
354
355 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
356 {
357     uint8_t *out = outp;
358
359     for( size_t i = 0; i < samples; i++ )
360         out[i] = in[i] ^ 0x80;
361 }
362
363 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
364 {
365     uint16_t *out = outp;
366
367     for( size_t i = 0; i < samples; i++ )
368     {
369         *(out++) = GetWBE( in ) - 0x8000;
370         in += 2;
371     }
372 }
373
374 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
375 {
376     uint16_t *out = outp;
377
378     for( size_t i = 0; i < samples; i++ )
379     {
380         *(out++) = GetWLE( in ) - 0x8000;
381         in += 2;
382     }
383 }
384
385 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
386 {
387     swab( in, out, samples * 2 );
388 }
389
390 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
391 {
392     int32_t *out = outp;
393
394     while( samples >= 2 )
395     {
396         uint32_t dw = U32_AT(in);
397         in += 4;
398         *(out++) = dw & ~0xFFF;
399         *(out++) = (dw << 20) | (*in << 12);
400         in++;
401         samples -= 2;
402     }
403
404     /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
405     if( samples )
406         *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
407 }
408
409 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
410 {
411     uint32_t *out = outp;
412
413     for( size_t i = 0; i < samples; i++ )
414     {
415         uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
416         *(out++) = s;
417         in += 3;
418     }
419 }
420
421 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
422 {
423     uint32_t *out = outp;
424
425     for( size_t i = 0; i < samples; i++ )
426     {
427         uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
428         *(out++) = s;
429         in += 3;
430     }
431 }
432
433 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
434 {
435     uint32_t *out = outp;
436
437     for( size_t i = 0; i < samples; i++ )
438     {
439         uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
440         *(out++) = s;
441         in += 3;
442     }
443 }
444
445 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
446 {
447     uint32_t *out = outp;
448
449     for( size_t i = 0; i < samples; i++ )
450     {
451         uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
452         *(out++) = s;
453         in += 3;
454     }
455 }
456
457 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
458 {
459     uint32_t *out = outp;
460
461     for( size_t i = 0; i < samples; i++ )
462     {
463         *(out++) = GetDWBE( in ) << 8;
464         in += 4;
465     }
466 }
467
468 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
469 {
470     uint32_t *out = outp;
471
472     for( size_t i = 0; i < samples; i++ )
473     {
474         *(out++) = GetDWLE( in ) << 8;
475         in += 4;
476     }
477 }
478
479 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
480 {
481     uint32_t *out = outp;
482
483     for( size_t i = 0; i < samples; i++ )
484     {
485         *(out++) = GetDWBE( in ) - 0x80000000;
486         in += 4;
487     }
488 }
489
490 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
491 {
492     uint32_t *out = outp;
493
494     for( size_t i = 0; i < samples; i++ )
495     {
496         *(out++) = GetDWLE( in ) - 0x80000000;
497         in += 4;
498     }
499 }
500
501 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
502 {
503     int32_t *out = outp;
504
505     for( size_t i = 0; i < samples; i++ )
506     {
507 #ifdef WORDS_BIGENDIAN
508         *(out++) = GetDWLE( in );
509 #else
510         *(out++) = GetDWBE( in );
511 #endif
512         in += 4;
513     }
514 }
515
516 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
517 {
518     float *out = outp;
519
520     for( size_t i = 0; i < samples; i++ )
521     {
522         union { float f; uint32_t u; } s;
523
524 #ifdef WORDS_BIGENDIAN
525         s.u = GetDWLE( in );
526 #else
527         s.u = GetDWBE( in );
528 #endif
529         *(out++) = s.f;
530         in += 4;
531     }
532 }
533
534 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
535 {
536     double *out = outp;
537
538     for( size_t i = 0; i < samples; i++ )
539     {
540         union { double d; uint64_t u; } s;
541
542 #ifdef WORDS_BIGENDIAN
543         s.u = GetQWLE( in );
544 #else
545         s.u = GetQWBE( in );
546 #endif
547         *(out++) = s.d;
548         in += 8;
549     }
550 }
551
552 static int16_t dat12tos16( uint16_t y )
553 {
554     static const uint16_t diff[16] = {
555        0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
556        0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000 };
557     static const uint8_t shift[16] = {
558         0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0 };
559
560     int d = y >> 8;
561     return (y - diff[d]) << shift[d];
562 }
563
564 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
565 {
566     int32_t *out = outp;
567
568     while( samples >= 2 )
569     {
570         *(out++) = dat12tos16(U16_AT(in) >> 4);
571         *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
572         in += 3;
573         samples -= 2;
574     }
575
576     if( samples )
577         *(out++) = dat12tos16(U16_AT(in) >> 4);
578 }
579
580 /*****************************************************************************
581  * DecoderClose: decoder destruction
582  *****************************************************************************/
583 static void DecoderClose( vlc_object_t *p_this )
584 {
585     decoder_t *p_dec = (decoder_t *)p_this;
586
587     free( p_dec->p_sys );
588 }
589
590 #ifdef ENABLE_SOUT
591 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
592  * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
593  * since decoded audio blocks must always be aligned. */
594
595 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
596 {
597     const uint16_t *in = (const uint16_t *)inp;
598     uint16_t *out = outp;
599
600     for( size_t i = 0; i < samples; i++ )
601         *(out++) =  bswap16( *(in++) + 0x8000 );
602 }
603
604 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
605 {
606     const uint16_t *in = (const uint16_t *)inp;
607     uint16_t *out = outp;
608
609     for( size_t i = 0; i < samples; i++ )
610         *(out++) =  *(in++) + 0x8000;
611 }
612
613 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
614 {
615     const uint32_t *in = (const uint32_t *)inp;
616     uint8_t *out = outp;
617
618     for( size_t i = 0; i < samples; i++ )
619     {
620         uint32_t s = *(in++);
621         *(out++) = (s >> 24) + 0x80;
622         *(out++) = (s >> 16);
623         *(out++) = (s >>  8);
624     }
625 }
626
627 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
628 {
629     const uint32_t *in = (const uint32_t *)inp;
630     uint8_t *out = outp;
631
632     for( size_t i = 0; i < samples; i++ )
633     {
634         uint32_t s = *(in++);
635         *(out++) = (s >>  8);
636         *(out++) = (s >> 16);
637         *(out++) = (s >> 24) + 0x80;
638     }
639 }
640
641 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
642 {
643     const uint32_t *in = (const uint32_t *)inp;
644     uint8_t *out = outp;
645
646     for( size_t i = 0; i < samples; i++ )
647     {
648         uint32_t s = *(in++);
649         *(out++) = (s >> 24);
650         *(out++) = (s >> 16);
651         *(out++) = (s >>  8);
652     }
653 }
654
655 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
656 {
657     const uint32_t *in = (const uint32_t *)inp;
658     uint8_t *out = outp;
659
660     for( size_t i = 0; i < samples; i++ )
661     {
662         uint32_t s = *(in++);
663         *(out++) = (s >>  8);
664         *(out++) = (s >> 16);
665         *(out++) = (s >> 24);
666     }
667 }
668
669 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
670 {
671     const uint32_t *in = (const uint32_t *)inp;
672     uint32_t *out = outp;
673
674     for( size_t i = 0; i < samples; i++ )
675         *(out++) =  bswap32( *(in++) + 0x80000000 );
676 }
677
678 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
679 {
680     const uint32_t *in = (const uint32_t *)inp;
681     uint32_t *out = outp;
682
683     for( size_t i = 0; i < samples; i++ )
684         *(out++) =  *(in++) + 0x80000000;
685 }
686
687 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
688 {
689     const int32_t *in = (const int32_t *)inp;
690     int32_t *out = outp;
691
692     for( size_t i = 0; i < samples; i++ )
693         *(out++) = bswap32( *(in++) );
694 }
695
696 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
697 {
698     const float *in = (const float *)inp;
699     uint8_t *out = outp;
700
701     for( size_t i = 0; i < samples; i++ )
702     {
703         union { float f; uint32_t u; char b[4]; } s;
704
705         s.f = *(in++);
706         s.u = bswap32( s.u );
707         memcpy( out, s.b, 4 );
708         out += 4;
709     }
710 }
711
712 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
713 {
714     const double *in = (const double *)inp;
715     uint8_t *out = outp;
716
717     for( size_t i = 0; i < samples; i++ )
718     {
719         union { double d; uint64_t u; char b[8]; } s;
720
721         s.d = *(in++);
722         s.u = bswap64( s.u );
723         memcpy( out, s.b, 8 );
724         out += 8;
725     }
726 }
727
728 static block_t *Encode( encoder_t *enc, block_t *in )
729 {
730     if( in == NULL )
731         return NULL;
732
733     block_t *out = block_Alloc( in->i_nb_samples
734                                 * enc->fmt_out.audio.i_bytes_per_frame );
735     if( unlikely(out == NULL) )
736         return NULL;
737
738     out->i_flags      = in->i_flags;
739     out->i_nb_samples = in->i_nb_samples;
740     out->i_dts        = in->i_dts;
741     out->i_pts        = in->i_pts;
742     out->i_length     = in->i_length;
743     out->i_nb_samples = in->i_nb_samples;
744
745     void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
746     if( encode != NULL )
747         encode( out->p_buffer, in->p_buffer, in->i_nb_samples
748                                              * enc->fmt_out.audio.i_channels );
749     else
750         memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
751     return out;
752 }
753
754 /**
755  * Probes the PCM audio encoder.
756  */
757 static int EncoderOpen( vlc_object_t *p_this )
758 {
759     encoder_t *p_enc = (encoder_t *)p_this;
760     void (*encode)(void *, const uint8_t *, unsigned) = NULL;
761
762     switch( p_enc->fmt_out.i_codec )
763     {
764     case VLC_CODEC_S8:
765         encode = S8Decode;
766     case VLC_CODEC_U8:
767         p_enc->fmt_in.i_codec = VLC_CODEC_U8;
768         p_enc->fmt_out.audio.i_bitspersample = 8;
769         break;
770     case VLC_CODEC_U16I:
771         encode = U16IEncode;
772         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
773         p_enc->fmt_out.audio.i_bitspersample = 16;
774         break;
775     case VLC_CODEC_U16N:
776         encode = U16NEncode;
777         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
778         p_enc->fmt_out.audio.i_bitspersample = 16;
779         break;
780     case VLC_CODEC_S16I:
781         encode = S16IDecode;
782     case VLC_CODEC_S16N:
783         p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
784         p_enc->fmt_out.audio.i_bitspersample = 16;
785         break;
786     case VLC_CODEC_U24B:
787         encode = U24BEncode;
788         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
789         p_enc->fmt_out.audio.i_bitspersample = 24;
790         break;
791     case VLC_CODEC_U24L:
792         encode = U24LEncode;
793         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
794         p_enc->fmt_out.audio.i_bitspersample = 24;
795         break;
796     case VLC_CODEC_S24B:
797         encode = S24BEncode;
798         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
799         p_enc->fmt_out.audio.i_bitspersample = 24;
800         break;
801     case VLC_CODEC_S24L:
802         encode = S24LEncode;
803         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
804         p_enc->fmt_out.audio.i_bitspersample = 24;
805         break;
806     case VLC_CODEC_U32I:
807         encode = U32IEncode;
808         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
809         p_enc->fmt_out.audio.i_bitspersample = 32;
810         break;
811     case VLC_CODEC_U32N:
812         encode = U32NEncode;
813         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
814         p_enc->fmt_out.audio.i_bitspersample = 32;
815         break;
816     case VLC_CODEC_S32I:
817         encode = S32IEncode;
818     case VLC_CODEC_S32N:
819         p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
820         p_enc->fmt_out.audio.i_bitspersample = 32;
821         break;
822 #ifdef WORDS_BIGENDIAN
823     case VLC_CODEC_F32L:
824 #else
825     case VLC_CODEC_F32B:
826 #endif
827         encode = F32IEncode;
828     case VLC_CODEC_FL32:
829         p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
830         p_enc->fmt_out.audio.i_bitspersample = 32;
831         break;
832 #ifdef WORDS_BIGENDIAN
833     case VLC_CODEC_F64L:
834 #else
835     case VLC_CODEC_F64B:
836 #endif
837         encode = F64IEncode;
838     case VLC_CODEC_FL64:
839         p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
840         p_enc->fmt_out.audio.i_bitspersample = 64;
841         break;
842     default:
843         return VLC_EGENERIC;
844     }
845
846     p_enc->p_sys = (void *)encode;
847     p_enc->pf_encode_audio = Encode;
848     p_enc->fmt_out.audio.i_bytes_per_frame =
849         (p_enc->fmt_out.audio.i_bitspersample / 8) *
850         p_enc->fmt_in.audio.i_channels;
851     p_enc->fmt_out.i_bitrate =
852         p_enc->fmt_in.audio.i_channels *
853         p_enc->fmt_in.audio.i_rate *
854         p_enc->fmt_out.audio.i_bitspersample;
855
856     msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
857              p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
858              p_enc->fmt_out.audio.i_bitspersample );
859
860     return VLC_SUCCESS;
861 }
862 #endif /* ENABLE_SOUT */