input: add input_SetProgramId
[vlc.git] / modules / codec / araw.c
blobc8c921414eadf116d6412f49b66409b9ffa644e6
1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VLC authors and VideoLAN
6 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8 * This program is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU Lesser General Public License as published by
10 * the Free Software Foundation; either version 2.1 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public License
19 * along with this program; if not, write to the Free Software Foundation,
20 * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
21 *****************************************************************************/
23 /*****************************************************************************
24 * Preamble
25 *****************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 # include "config.h"
28 #endif
30 #include <math.h>
31 #include <assert.h>
33 #include <vlc_common.h>
34 #include <vlc_plugin.h>
35 #include <vlc_codec.h>
36 #include <vlc_aout.h>
38 /*****************************************************************************
39 * Module descriptor
40 *****************************************************************************/
41 static int DecoderOpen ( vlc_object_t * );
43 #ifdef ENABLE_SOUT
44 static int EncoderOpen ( vlc_object_t * );
45 #endif
47 vlc_module_begin ()
48 /* audio decoder module */
49 set_description( N_("Raw/Log Audio decoder") )
50 set_capability( "audio decoder", 100 )
51 set_category( CAT_INPUT )
52 set_subcategory( SUBCAT_INPUT_ACODEC )
53 set_callback( DecoderOpen )
55 #ifdef ENABLE_SOUT
56 /* audio encoder submodule */
57 add_submodule ()
58 set_description( N_("Raw audio encoder") )
59 set_capability( "encoder", 150 )
60 set_callback( EncoderOpen )
61 #endif
62 vlc_module_end ()
64 /*****************************************************************************
65 * Local prototypes
66 *****************************************************************************/
67 static int DecodeBlock( decoder_t *, block_t * );
68 static void Flush( decoder_t * );
70 typedef struct
72 void (*decode) (void *, const uint8_t *, unsigned);
73 size_t framebits;
74 date_t end_date;
75 } decoder_sys_t;
77 static void S8Decode( void *, const uint8_t *, unsigned );
78 static void U16BDecode( void *, const uint8_t *, unsigned );
79 static void U16LDecode( void *, const uint8_t *, unsigned );
80 static void S16IDecode( void *, const uint8_t *, unsigned );
81 static void S20BDecode( void *, const uint8_t *, unsigned );
82 static void U24BDecode( void *, const uint8_t *, unsigned );
83 static void U24LDecode( void *, const uint8_t *, unsigned );
84 static void S24BDecode( void *, const uint8_t *, unsigned );
85 static void S24LDecode( void *, const uint8_t *, unsigned );
86 static void S24B32Decode( void *, const uint8_t *, unsigned );
87 static void S24L32Decode( void *, const uint8_t *, unsigned );
88 static void U32BDecode( void *, const uint8_t *, unsigned );
89 static void U32LDecode( void *, const uint8_t *, unsigned );
90 static void S32IDecode( void *, const uint8_t *, unsigned );
91 static void F32NDecode( void *, const uint8_t *, unsigned );
92 static void F32IDecode( void *, const uint8_t *, unsigned );
93 static void F64NDecode( void *, const uint8_t *, unsigned );
94 static void F64IDecode( void *, const uint8_t *, unsigned );
95 static void DAT12Decode( void *, const uint8_t *, unsigned );
97 /*****************************************************************************
98 * DecoderOpen: probe the decoder and return score
99 *****************************************************************************/
100 static int DecoderOpen( vlc_object_t *p_this )
102 decoder_t *p_dec = (decoder_t*)p_this;
103 vlc_fourcc_t format = p_dec->fmt_in.i_codec;
105 switch( p_dec->fmt_in.i_codec )
107 case VLC_FOURCC('a','r','a','w'):
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 )
118 msg_Err( p_dec, "bad parameters(bits/sample)" );
119 return VLC_EGENERIC;
121 break;
124 void (*decode) (void *, const uint8_t *, unsigned) = NULL;
125 uint_fast8_t bits;
127 switch( format )
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 = F64IDecode;
136 bits = 64;
137 break;
138 case VLC_CODEC_FL64:
139 decode = F64NDecode;
140 bits = 64;
141 break;
142 #ifdef WORDS_BIGENDIAN
143 case VLC_CODEC_F32L:
144 #else
145 case VLC_CODEC_F32B:
146 #endif
147 format = VLC_CODEC_FL32;
148 decode = F32IDecode;
149 bits = 32;
150 break;
151 case VLC_CODEC_FL32:
152 decode = F32NDecode;
153 bits = 32;
154 break;
155 case VLC_CODEC_U32B:
156 format = VLC_CODEC_S32N;
157 decode = U32BDecode;
158 bits = 32;
159 break;
160 case VLC_CODEC_U32L:
161 format = VLC_CODEC_S32N;
162 decode = U32LDecode;
163 bits = 32;
164 break;
165 case VLC_CODEC_S32I:
166 format = VLC_CODEC_S32N;
167 decode = S32IDecode;
168 /* fall through */
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 /* fall through */
221 case VLC_CODEC_S16N:
222 bits = 16;
223 break;
224 case VLC_CODEC_DAT12:
225 format = VLC_CODEC_S16N;
226 decode = DAT12Decode;
227 bits = 12;
228 break;
229 case VLC_CODEC_S8:
230 decode = S8Decode;
231 format = VLC_CODEC_U8;
232 /* fall through */
233 case VLC_CODEC_U8:
234 bits = 8;
235 break;
236 default:
237 return VLC_EGENERIC;
240 if( p_dec->fmt_in.audio.i_channels == 0 ||
241 p_dec->fmt_in.audio.i_channels > INPUT_CHAN_MAX )
243 msg_Err( p_dec, "bad channels count (1-%i): %i",
244 AOUT_CHAN_MAX, p_dec->fmt_in.audio.i_channels );
245 return VLC_EGENERIC;
248 if( p_dec->fmt_in.audio.i_rate == 0 || p_dec->fmt_in.audio.i_rate > 384000 )
250 msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
251 return VLC_EGENERIC;
254 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
255 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
256 p_dec->fmt_in.audio.i_bitspersample );
258 /* Allocate the memory needed to store the decoder's structure */
259 decoder_sys_t *p_sys = vlc_obj_malloc(p_this, sizeof(*p_sys));
260 if( unlikely(p_sys == NULL) )
261 return VLC_ENOMEM;
263 /* Set output properties */
264 p_dec->fmt_out.i_codec = format;
265 p_dec->fmt_out.audio.channel_type = p_dec->fmt_in.audio.channel_type;
266 p_dec->fmt_out.audio.i_format = format;
267 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
268 if( p_dec->fmt_in.audio.i_channels < ARRAY_SIZE(vlc_chan_maps) )
270 if( p_dec->fmt_in.audio.i_physical_channels )
271 p_dec->fmt_out.audio.i_physical_channels =
272 p_dec->fmt_in.audio.i_physical_channels;
273 else
274 p_dec->fmt_out.audio.i_physical_channels =
275 vlc_chan_maps[p_dec->fmt_in.audio.i_channels];
277 else
279 /* Unknown channel map, let the aout/filters decide what to do */
280 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
281 p_dec->fmt_out.audio.i_physical_channels = 0;
283 aout_FormatPrepare( &p_dec->fmt_out.audio );
285 p_sys->decode = decode;
286 p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
287 assert( p_sys->framebits );
289 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
291 p_dec->pf_decode = DecodeBlock;
292 p_dec->pf_flush = Flush;
293 p_dec->p_sys = p_sys;
295 return VLC_SUCCESS;
298 /*****************************************************************************
299 * Flush:
300 *****************************************************************************/
301 static void Flush( decoder_t *p_dec )
303 decoder_sys_t *p_sys = p_dec->p_sys;
305 date_Set( &p_sys->end_date, VLC_TICK_INVALID );
308 /****************************************************************************
309 * DecodeBlock: the whole thing
310 ****************************************************************************
311 * This function must be fed with whole samples (see nBlockAlign).
312 ****************************************************************************/
313 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
315 decoder_sys_t *p_sys = p_dec->p_sys;
316 if( p_block == NULL ) /* No Drain */
317 return VLCDEC_SUCCESS;
319 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
321 Flush( p_dec );
322 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
323 goto skip;
326 if( p_block->i_pts != VLC_TICK_INVALID &&
327 p_block->i_pts != date_Get( &p_sys->end_date ) )
329 date_Set( &p_sys->end_date, p_block->i_pts );
331 else if( date_Get( &p_sys->end_date ) == VLC_TICK_INVALID )
332 /* We've just started the stream, wait for the first PTS. */
333 goto skip;
335 unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
336 if( samples == 0 )
337 goto skip;
339 if( p_sys->decode != NULL )
341 if( decoder_UpdateAudioFormat( p_dec ) )
342 goto skip;
343 block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
344 if( p_out == NULL )
345 goto skip;
347 p_sys->decode( p_out->p_buffer, p_block->p_buffer,
348 samples * p_dec->fmt_in.audio.i_channels );
349 block_Release( p_block );
350 p_block = p_out;
352 else
354 if( decoder_UpdateAudioFormat( p_dec ) )
355 goto skip;
356 p_block->i_nb_samples = samples;
357 p_block->i_buffer = samples * (p_sys->framebits / 8);
360 p_block->i_pts = date_Get( &p_sys->end_date );
361 p_block->i_length = date_Increment( &p_sys->end_date, samples )
362 - p_block->i_pts;
363 decoder_QueueAudio( p_dec, p_block );
364 return VLCDEC_SUCCESS;
365 skip:
366 block_Release( p_block );
367 return VLCDEC_SUCCESS;
370 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
372 uint8_t *out = outp;
374 for( size_t i = 0; i < samples; i++ )
375 out[i] = in[i] ^ 0x80;
378 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
380 uint16_t *out = outp;
382 for( size_t i = 0; i < samples; i++ )
384 *(out++) = GetWBE( in ) - 0x8000;
385 in += 2;
389 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
391 uint16_t *out = outp;
393 for( size_t i = 0; i < samples; i++ )
395 *(out++) = GetWLE( in ) - 0x8000;
396 in += 2;
400 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
402 swab( in, out, samples * 2 );
405 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
407 int32_t *out = outp;
409 while( samples >= 2 )
411 uint32_t dw = U32_AT(in);
412 in += 4;
413 *(out++) = dw & ~0xFFF;
414 *(out++) = (dw << 20) | (*in << 12);
415 in++;
416 samples -= 2;
419 /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
420 if( samples )
421 *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
424 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
426 uint32_t *out = outp;
428 for( size_t i = 0; i < samples; i++ )
430 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
431 *(out++) = s;
432 in += 3;
436 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
438 uint32_t *out = outp;
440 for( size_t i = 0; i < samples; i++ )
442 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
443 *(out++) = s;
444 in += 3;
448 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
450 uint32_t *out = outp;
452 for( size_t i = 0; i < samples; i++ )
454 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
455 *(out++) = s;
456 in += 3;
460 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
462 uint32_t *out = outp;
464 for( size_t i = 0; i < samples; i++ )
466 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
467 *(out++) = s;
468 in += 3;
472 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
474 uint32_t *out = outp;
476 for( size_t i = 0; i < samples; i++ )
478 *(out++) = GetDWBE( in ) << 8;
479 in += 4;
483 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
485 uint32_t *out = outp;
487 for( size_t i = 0; i < samples; i++ )
489 *(out++) = GetDWLE( in ) << 8;
490 in += 4;
494 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
496 uint32_t *out = outp;
498 for( size_t i = 0; i < samples; i++ )
500 *(out++) = GetDWBE( in ) - 0x80000000;
501 in += 4;
505 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
507 uint32_t *out = outp;
509 for( size_t i = 0; i < samples; i++ )
511 *(out++) = GetDWLE( in ) - 0x80000000;
512 in += 4;
516 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
518 int32_t *out = outp;
520 for( size_t i = 0; i < samples; i++ )
522 #ifdef WORDS_BIGENDIAN
523 *(out++) = GetDWLE( in );
524 #else
525 *(out++) = GetDWBE( in );
526 #endif
527 in += 4;
531 static void F32NDecode( void *outp, const uint8_t *in, unsigned samples )
533 float *out = outp;
535 for( size_t i = 0; i < samples; i++ )
537 memcpy( out, in, sizeof(float) );
538 if( unlikely(!isfinite(*out)) )
539 *out = 0.f;
540 out++;
541 in += sizeof(float);
545 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
547 float *out = outp;
549 for( size_t i = 0; i < samples; i++ )
551 union { float f; uint32_t u; } s;
553 #ifdef WORDS_BIGENDIAN
554 s.u = GetDWLE( in );
555 #else
556 s.u = GetDWBE( in );
557 #endif
558 if( unlikely(!isfinite(s.f)) )
559 s.f = 0.f;
560 *(out++) = s.f;
561 in += 4;
565 static void F64NDecode( void *outp, const uint8_t *in, unsigned samples )
567 double *out = outp;
569 for( size_t i = 0; i < samples; i++ )
571 memcpy( out, in, sizeof(double) );
572 if( unlikely(!isfinite( *out )) )
573 *out = 0.;
574 out++;
575 in += sizeof(double);
579 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
581 double *out = outp;
583 for( size_t i = 0; i < samples; i++ )
585 union { double d; uint64_t u; } s;
587 #ifdef WORDS_BIGENDIAN
588 s.u = GetQWLE( in );
589 #else
590 s.u = GetQWBE( in );
591 #endif
592 if( unlikely(!isfinite( s.d )) )
593 s.d = 0.;
594 *(out++) = s.d;
595 in += 8;
599 static int_fast16_t dat12tos16( uint_fast16_t y )
601 static const int16_t diff[16] = {
602 0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
603 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000,
605 static const uint8_t shift[16] = {
606 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0
609 assert(y < 0x1000);
611 int d = y >> 8;
612 return ((int)y - diff[d]) << shift[d];
615 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
617 int16_t *out = outp;
619 while( samples >= 2 )
621 *(out++) = dat12tos16(U16_AT(in) >> 4);
622 *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
623 in += 3;
624 samples -= 2;
627 if( samples )
628 *(out++) = dat12tos16(U16_AT(in) >> 4);
631 #ifdef ENABLE_SOUT
632 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
633 * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
634 * since decoded audio blocks must always be aligned. */
636 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
638 const uint16_t *in = (const uint16_t *)inp;
639 uint16_t *out = outp;
641 for( size_t i = 0; i < samples; i++ )
642 *(out++) = vlc_bswap16( *(in++) + 0x8000 );
645 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
647 const uint16_t *in = (const uint16_t *)inp;
648 uint16_t *out = outp;
650 for( size_t i = 0; i < samples; i++ )
651 *(out++) = *(in++) + 0x8000;
654 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
656 const uint32_t *in = (const uint32_t *)inp;
657 uint8_t *out = outp;
659 for( size_t i = 0; i < samples; i++ )
661 uint32_t s = *(in++);
662 *(out++) = (s >> 24) + 0x80;
663 *(out++) = (s >> 16);
664 *(out++) = (s >> 8);
668 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
670 const uint32_t *in = (const uint32_t *)inp;
671 uint8_t *out = outp;
673 for( size_t i = 0; i < samples; i++ )
675 uint32_t s = *(in++);
676 *(out++) = (s >> 8);
677 *(out++) = (s >> 16);
678 *(out++) = (s >> 24) + 0x80;
682 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
684 const uint32_t *in = (const uint32_t *)inp;
685 uint8_t *out = outp;
687 for( size_t i = 0; i < samples; i++ )
689 uint32_t s = *(in++);
690 *(out++) = (s >> 24);
691 *(out++) = (s >> 16);
692 *(out++) = (s >> 8);
696 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
698 const uint32_t *in = (const uint32_t *)inp;
699 uint8_t *out = outp;
701 for( size_t i = 0; i < samples; i++ )
703 uint32_t s = *(in++);
704 *(out++) = (s >> 8);
705 *(out++) = (s >> 16);
706 *(out++) = (s >> 24);
710 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
712 const uint32_t *in = (const uint32_t *)inp;
713 uint32_t *out = outp;
715 for( size_t i = 0; i < samples; i++ )
716 *(out++) = vlc_bswap32( *(in++) + 0x80000000 );
719 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
721 const uint32_t *in = (const uint32_t *)inp;
722 uint32_t *out = outp;
724 for( size_t i = 0; i < samples; i++ )
725 *(out++) = *(in++) + 0x80000000;
728 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
730 const int32_t *in = (const int32_t *)inp;
731 int32_t *out = outp;
733 for( size_t i = 0; i < samples; i++ )
734 *(out++) = vlc_bswap32( *(in++) );
737 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
739 const float *in = (const float *)inp;
740 uint8_t *out = outp;
742 for( size_t i = 0; i < samples; i++ )
744 union { float f; uint32_t u; char b[4]; } s;
746 s.f = *(in++);
747 s.u = vlc_bswap32( s.u );
748 memcpy( out, s.b, 4 );
749 out += 4;
753 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
755 const double *in = (const double *)inp;
756 uint8_t *out = outp;
758 for( size_t i = 0; i < samples; i++ )
760 union { double d; uint64_t u; char b[8]; } s;
762 s.d = *(in++);
763 s.u = vlc_bswap64( s.u );
764 memcpy( out, s.b, 8 );
765 out += 8;
769 static block_t *Encode( encoder_t *enc, block_t *in )
771 if( in == NULL )
772 return NULL;
774 block_t *out = block_Alloc( in->i_nb_samples
775 * enc->fmt_out.audio.i_bytes_per_frame );
776 if( unlikely(out == NULL) )
777 return NULL;
779 out->i_flags = in->i_flags;
780 out->i_nb_samples = in->i_nb_samples;
781 out->i_dts = in->i_dts;
782 out->i_pts = in->i_pts;
783 out->i_length = in->i_length;
785 void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
786 if( encode != NULL )
787 encode( out->p_buffer, in->p_buffer, in->i_nb_samples
788 * enc->fmt_out.audio.i_channels );
789 else {
790 assert( out->i_buffer >= in->i_buffer );
791 memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
793 return out;
797 * Probes the PCM audio encoder.
799 static int EncoderOpen( vlc_object_t *p_this )
801 encoder_t *p_enc = (encoder_t *)p_this;
802 void (*encode)(void *, const uint8_t *, unsigned) = NULL;
804 switch( p_enc->fmt_out.i_codec )
806 case VLC_CODEC_S8:
807 encode = S8Decode;
808 /* fall through */
809 case VLC_CODEC_U8:
810 p_enc->fmt_in.i_codec = VLC_CODEC_U8;
811 p_enc->fmt_out.audio.i_bitspersample = 8;
812 break;
813 case VLC_CODEC_U16I:
814 encode = U16IEncode;
815 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
816 p_enc->fmt_out.audio.i_bitspersample = 16;
817 break;
818 case VLC_CODEC_U16N:
819 encode = U16NEncode;
820 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
821 p_enc->fmt_out.audio.i_bitspersample = 16;
822 break;
823 case VLC_CODEC_S16I:
824 encode = S16IDecode;
825 /* fall through */
826 case VLC_CODEC_S16N:
827 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
828 p_enc->fmt_out.audio.i_bitspersample = 16;
829 break;
830 case VLC_CODEC_U24B:
831 encode = U24BEncode;
832 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
833 p_enc->fmt_out.audio.i_bitspersample = 24;
834 break;
835 case VLC_CODEC_U24L:
836 encode = U24LEncode;
837 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
838 p_enc->fmt_out.audio.i_bitspersample = 24;
839 break;
840 case VLC_CODEC_S24B:
841 encode = S24BEncode;
842 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
843 p_enc->fmt_out.audio.i_bitspersample = 24;
844 break;
845 case VLC_CODEC_S24L:
846 encode = S24LEncode;
847 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
848 p_enc->fmt_out.audio.i_bitspersample = 24;
849 break;
850 case VLC_CODEC_U32I:
851 encode = U32IEncode;
852 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
853 p_enc->fmt_out.audio.i_bitspersample = 32;
854 break;
855 case VLC_CODEC_U32N:
856 encode = U32NEncode;
857 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
858 p_enc->fmt_out.audio.i_bitspersample = 32;
859 break;
860 case VLC_CODEC_S32I:
861 encode = S32IEncode;
862 /* fall through */
863 case VLC_CODEC_S32N:
864 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
865 p_enc->fmt_out.audio.i_bitspersample = 32;
866 break;
867 #ifdef WORDS_BIGENDIAN
868 case VLC_CODEC_F32L:
869 #else
870 case VLC_CODEC_F32B:
871 #endif
872 encode = F32IEncode;
873 /* fall through */
874 case VLC_CODEC_FL32:
875 p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
876 p_enc->fmt_out.audio.i_bitspersample = 32;
877 break;
878 #ifdef WORDS_BIGENDIAN
879 case VLC_CODEC_F64L:
880 #else
881 case VLC_CODEC_F64B:
882 #endif
883 encode = F64IEncode;
884 /* fall through */
885 case VLC_CODEC_FL64:
886 p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
887 p_enc->fmt_out.audio.i_bitspersample = 64;
888 break;
889 default:
890 return VLC_EGENERIC;
893 p_enc->p_sys = (void *)encode;
894 p_enc->pf_encode_audio = Encode;
895 p_enc->fmt_out.audio.i_bytes_per_frame =
896 (p_enc->fmt_out.audio.i_bitspersample / 8) *
897 p_enc->fmt_in.audio.i_channels;
898 p_enc->fmt_out.i_bitrate =
899 p_enc->fmt_in.audio.i_channels *
900 p_enc->fmt_in.audio.i_rate *
901 p_enc->fmt_out.audio.i_bitspersample;
903 msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
904 p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
905 p_enc->fmt_out.audio.i_bitspersample );
907 return VLC_SUCCESS;
909 #endif /* ENABLE_SOUT */