demux: mp4: avoid audio cuts on seek
[vlc.git] / modules / codec / araw.c
blobfcac471d73d023fa6cdd5435083896be341b8193
1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2003 VLC authors and VideoLAN
5 * $Id$
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
25 * Preamble
26 *****************************************************************************/
27 #ifdef HAVE_CONFIG_H
28 # include "config.h"
29 #endif
31 #include <math.h>
32 #include <assert.h>
34 #include <vlc_common.h>
35 #include <vlc_plugin.h>
36 #include <vlc_codec.h>
37 #include <vlc_aout.h>
39 /*****************************************************************************
40 * Module descriptor
41 *****************************************************************************/
42 static int DecoderOpen ( vlc_object_t * );
43 static void DecoderClose( vlc_object_t * );
45 #ifdef ENABLE_SOUT
46 static int EncoderOpen ( vlc_object_t * );
47 #endif
49 vlc_module_begin ()
50 /* audio decoder module */
51 set_description( N_("Raw/Log Audio decoder") )
52 set_capability( "audio decoder", 100 )
53 set_category( CAT_INPUT )
54 set_subcategory( SUBCAT_INPUT_ACODEC )
55 set_callbacks( DecoderOpen, DecoderClose )
57 #ifdef ENABLE_SOUT
58 /* audio encoder submodule */
59 add_submodule ()
60 set_description( N_("Raw audio encoder") )
61 set_capability( "encoder", 150 )
62 set_callbacks( EncoderOpen, NULL )
63 #endif
64 vlc_module_end ()
66 /*****************************************************************************
67 * Local prototypes
68 *****************************************************************************/
69 static int DecodeBlock( decoder_t *, block_t * );
70 static void Flush( decoder_t * );
72 struct decoder_sys_t
74 void (*decode) (void *, const uint8_t *, unsigned);
75 size_t framebits;
76 date_t end_date;
79 static const uint16_t pi_channels_maps[] =
82 AOUT_CHAN_CENTER, AOUT_CHANS_2_0, AOUT_CHANS_3_0,
83 AOUT_CHANS_4_0, AOUT_CHANS_5_0, AOUT_CHANS_5_1,
84 AOUT_CHANS_7_0, AOUT_CHANS_7_1, AOUT_CHANS_8_1,
86 static_assert( ARRAY_SIZE( pi_channels_maps ) - 1 <= AOUT_CHAN_MAX,
87 "channel count mismatch" );
89 static void S8Decode( void *, const uint8_t *, unsigned );
90 static void U16BDecode( void *, const uint8_t *, unsigned );
91 static void U16LDecode( void *, const uint8_t *, unsigned );
92 static void S16IDecode( void *, const uint8_t *, unsigned );
93 static void S20BDecode( void *, const uint8_t *, unsigned );
94 static void U24BDecode( void *, const uint8_t *, unsigned );
95 static void U24LDecode( void *, const uint8_t *, unsigned );
96 static void S24BDecode( void *, const uint8_t *, unsigned );
97 static void S24LDecode( void *, const uint8_t *, unsigned );
98 static void S24B32Decode( void *, const uint8_t *, unsigned );
99 static void S24L32Decode( void *, const uint8_t *, unsigned );
100 static void U32BDecode( void *, const uint8_t *, unsigned );
101 static void U32LDecode( void *, const uint8_t *, unsigned );
102 static void S32IDecode( void *, const uint8_t *, unsigned );
103 static void F32NDecode( void *, const uint8_t *, unsigned );
104 static void F32IDecode( void *, const uint8_t *, unsigned );
105 static void F64NDecode( void *, const uint8_t *, unsigned );
106 static void F64IDecode( void *, const uint8_t *, unsigned );
107 static void DAT12Decode( void *, const uint8_t *, unsigned );
109 /*****************************************************************************
110 * DecoderOpen: probe the decoder and return score
111 *****************************************************************************/
112 static int DecoderOpen( vlc_object_t *p_this )
114 decoder_t *p_dec = (decoder_t*)p_this;
115 vlc_fourcc_t format = p_dec->fmt_in.i_codec;
117 switch( p_dec->fmt_in.i_codec )
119 case VLC_FOURCC('a','r','a','w'):
120 case VLC_FOURCC('a','f','l','t'):
121 /* _signed_ big endian samples (mov) */
122 case VLC_FOURCC('t','w','o','s'):
123 /* _signed_ little endian samples (mov) */
124 case VLC_FOURCC('s','o','w','t'):
125 format =
126 vlc_fourcc_GetCodecAudio( p_dec->fmt_in.i_codec,
127 p_dec->fmt_in.audio.i_bitspersample );
128 if( !format )
130 msg_Err( p_dec, "bad parameters(bits/sample)" );
131 return VLC_EGENERIC;
133 break;
136 void (*decode) (void *, const uint8_t *, unsigned) = NULL;
137 uint_fast8_t bits;
139 switch( format )
141 #ifdef WORDS_BIGENDIAN
142 case VLC_CODEC_F64L:
143 #else
144 case VLC_CODEC_F64B:
145 #endif
146 format = VLC_CODEC_FL64;
147 decode = F64IDecode;
148 bits = 64;
149 break;
150 case VLC_CODEC_FL64:
151 decode = F64NDecode;
152 bits = 64;
153 break;
154 #ifdef WORDS_BIGENDIAN
155 case VLC_CODEC_F32L:
156 #else
157 case VLC_CODEC_F32B:
158 #endif
159 format = VLC_CODEC_FL32;
160 decode = F32IDecode;
161 bits = 32;
162 break;
163 case VLC_CODEC_FL32:
164 decode = F32NDecode;
165 bits = 32;
166 break;
167 case VLC_CODEC_U32B:
168 format = VLC_CODEC_S32N;
169 decode = U32BDecode;
170 bits = 32;
171 break;
172 case VLC_CODEC_U32L:
173 format = VLC_CODEC_S32N;
174 decode = U32LDecode;
175 bits = 32;
176 break;
177 case VLC_CODEC_S32I:
178 format = VLC_CODEC_S32N;
179 decode = S32IDecode;
180 /* fall through */
181 case VLC_CODEC_S32N:
182 bits = 32;
183 break;
184 case VLC_CODEC_S24B32:
185 format = VLC_CODEC_S32N;
186 decode = S24B32Decode;
187 bits = 32;
188 break;
189 case VLC_CODEC_S24L32:
190 format = VLC_CODEC_S32N;
191 decode = S24L32Decode;
192 bits = 32;
193 break;
194 case VLC_CODEC_U24B:
195 format = VLC_CODEC_S32N;
196 decode = U24BDecode;
197 bits = 24;
198 break;
199 case VLC_CODEC_U24L:
200 format = VLC_CODEC_S32N;
201 decode = U24LDecode;
202 bits = 24;
203 break;
204 case VLC_CODEC_S24B:
205 format = VLC_CODEC_S32N;
206 decode = S24BDecode;
207 bits = 24;
208 break;
209 case VLC_CODEC_S24L:
210 format = VLC_CODEC_S32N;
211 decode = S24LDecode;
212 bits = 24;
213 break;
214 case VLC_CODEC_S20B:
215 format = VLC_CODEC_S32N;
216 decode = S20BDecode;
217 bits = 20;
218 break;
219 case VLC_CODEC_U16B:
220 format = VLC_CODEC_S16N;
221 decode = U16BDecode;
222 bits = 16;
223 break;
224 case VLC_CODEC_U16L:
225 format = VLC_CODEC_S16N;
226 decode = U16LDecode;
227 bits = 16;
228 break;
229 case VLC_CODEC_S16I:
230 format = VLC_CODEC_S16N;
231 decode = S16IDecode;
232 /* fall through */
233 case VLC_CODEC_S16N:
234 bits = 16;
235 break;
236 case VLC_CODEC_DAT12:
237 format = VLC_CODEC_S16N;
238 decode = DAT12Decode;
239 bits = 12;
240 break;
241 case VLC_CODEC_S8:
242 decode = S8Decode;
243 format = VLC_CODEC_U8;
244 /* fall through */
245 case VLC_CODEC_U8:
246 bits = 8;
247 break;
248 default:
249 return VLC_EGENERIC;
252 if( p_dec->fmt_in.audio.i_channels == 0 ||
253 p_dec->fmt_in.audio.i_channels > INPUT_CHAN_MAX )
255 msg_Err( p_dec, "bad channels count (1-%i): %i",
256 AOUT_CHAN_MAX, p_dec->fmt_in.audio.i_channels );
257 return VLC_EGENERIC;
260 if( p_dec->fmt_in.audio.i_rate == 0 || p_dec->fmt_in.audio.i_rate > 384000 )
262 msg_Err( p_dec, "bad samplerate: %d Hz", p_dec->fmt_in.audio.i_rate );
263 return VLC_EGENERIC;
266 msg_Dbg( p_dec, "samplerate:%dHz channels:%d bits/sample:%d",
267 p_dec->fmt_in.audio.i_rate, p_dec->fmt_in.audio.i_channels,
268 p_dec->fmt_in.audio.i_bitspersample );
270 /* Allocate the memory needed to store the decoder's structure */
271 decoder_sys_t *p_sys = malloc(sizeof(*p_sys));
272 if( unlikely(p_sys == NULL) )
273 return VLC_ENOMEM;
275 /* Set output properties */
276 p_dec->fmt_out.i_codec = format;
277 p_dec->fmt_out.audio.channel_type = p_dec->fmt_in.audio.channel_type;
278 p_dec->fmt_out.audio.i_format = format;
279 p_dec->fmt_out.audio.i_rate = p_dec->fmt_in.audio.i_rate;
280 if( p_dec->fmt_in.audio.i_channels <= ARRAY_SIZE( pi_channels_maps ) - 1 )
282 if( p_dec->fmt_in.audio.i_physical_channels )
283 p_dec->fmt_out.audio.i_physical_channels =
284 p_dec->fmt_in.audio.i_physical_channels;
285 else
286 p_dec->fmt_out.audio.i_physical_channels =
287 pi_channels_maps[p_dec->fmt_in.audio.i_channels];
289 else
291 /* Unknown channel map, let the aout/filters decide what to do */
292 p_dec->fmt_out.audio.i_channels = p_dec->fmt_in.audio.i_channels;
293 p_dec->fmt_out.audio.i_physical_channels = 0;
295 aout_FormatPrepare( &p_dec->fmt_out.audio );
297 p_sys->decode = decode;
298 p_sys->framebits = bits * p_dec->fmt_out.audio.i_channels;
299 assert( p_sys->framebits );
301 date_Init( &p_sys->end_date, p_dec->fmt_out.audio.i_rate, 1 );
302 date_Set( &p_sys->end_date, 0 );
304 p_dec->pf_decode = DecodeBlock;
305 p_dec->pf_flush = Flush;
306 p_dec->p_sys = p_sys;
308 return VLC_SUCCESS;
311 /*****************************************************************************
312 * Flush:
313 *****************************************************************************/
314 static void Flush( decoder_t *p_dec )
316 decoder_sys_t *p_sys = p_dec->p_sys;
318 date_Set( &p_sys->end_date, 0 );
321 /****************************************************************************
322 * DecodeBlock: the whole thing
323 ****************************************************************************
324 * This function must be fed with whole samples (see nBlockAlign).
325 ****************************************************************************/
326 static int DecodeBlock( decoder_t *p_dec, block_t *p_block )
328 decoder_sys_t *p_sys = p_dec->p_sys;
329 if( p_block == NULL ) /* No Drain */
330 return VLCDEC_SUCCESS;
332 if( p_block->i_flags & (BLOCK_FLAG_CORRUPTED|BLOCK_FLAG_DISCONTINUITY) )
334 Flush( p_dec );
335 if( p_block->i_flags & BLOCK_FLAG_CORRUPTED )
336 goto skip;
339 if( p_block->i_pts > VLC_TS_INVALID &&
340 p_block->i_pts != date_Get( &p_sys->end_date ) )
342 date_Set( &p_sys->end_date, p_block->i_pts );
344 else if( !date_Get( &p_sys->end_date ) )
345 /* We've just started the stream, wait for the first PTS. */
346 goto skip;
348 unsigned samples = (8 * p_block->i_buffer) / p_sys->framebits;
349 if( samples == 0 )
350 goto skip;
352 if( p_sys->decode != NULL )
354 if( decoder_UpdateAudioFormat( p_dec ) )
355 goto skip;
356 block_t *p_out = decoder_NewAudioBuffer( p_dec, samples );
357 if( p_out == NULL )
358 goto skip;
360 p_sys->decode( p_out->p_buffer, p_block->p_buffer,
361 samples * p_dec->fmt_in.audio.i_channels );
362 block_Release( p_block );
363 p_block = p_out;
365 else
367 if( decoder_UpdateAudioFormat( p_dec ) )
368 goto skip;
369 p_block->i_nb_samples = samples;
370 p_block->i_buffer = samples * (p_sys->framebits / 8);
373 p_block->i_pts = date_Get( &p_sys->end_date );
374 p_block->i_length = date_Increment( &p_sys->end_date, samples )
375 - p_block->i_pts;
376 decoder_QueueAudio( p_dec, p_block );
377 return VLCDEC_SUCCESS;
378 skip:
379 block_Release( p_block );
380 return VLCDEC_SUCCESS;
383 static void S8Decode( void *outp, const uint8_t *in, unsigned samples )
385 uint8_t *out = outp;
387 for( size_t i = 0; i < samples; i++ )
388 out[i] = in[i] ^ 0x80;
391 static void U16BDecode( void *outp, const uint8_t *in, unsigned samples )
393 uint16_t *out = outp;
395 for( size_t i = 0; i < samples; i++ )
397 *(out++) = GetWBE( in ) - 0x8000;
398 in += 2;
402 static void U16LDecode( void *outp, const uint8_t *in, unsigned samples )
404 uint16_t *out = outp;
406 for( size_t i = 0; i < samples; i++ )
408 *(out++) = GetWLE( in ) - 0x8000;
409 in += 2;
413 static void S16IDecode( void *out, const uint8_t *in, unsigned samples )
415 swab( in, out, samples * 2 );
418 static void S20BDecode( void *outp, const uint8_t *in, unsigned samples )
420 int32_t *out = outp;
422 while( samples >= 2 )
424 uint32_t dw = U32_AT(in);
425 in += 4;
426 *(out++) = dw & ~0xFFF;
427 *(out++) = (dw << 20) | (*in << 12);
428 in++;
429 samples -= 2;
432 /* No U32_AT() for the last odd sample: avoid off-by-one overflow! */
433 if( samples )
434 *(out++) = (U16_AT(in) << 16) | ((in[2] & 0xF0) << 8);
437 static void U24BDecode( void *outp, const uint8_t *in, unsigned samples )
439 uint32_t *out = outp;
441 for( size_t i = 0; i < samples; i++ )
443 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8)) - 0x80000000;
444 *(out++) = s;
445 in += 3;
449 static void U24LDecode( void *outp, const uint8_t *in, unsigned samples )
451 uint32_t *out = outp;
453 for( size_t i = 0; i < samples; i++ )
455 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8)) - 0x80000000;
456 *(out++) = s;
457 in += 3;
461 static void S24BDecode( void *outp, const uint8_t *in, unsigned samples )
463 uint32_t *out = outp;
465 for( size_t i = 0; i < samples; i++ )
467 uint32_t s = ((in[0] << 24) | (in[1] << 16) | (in[2] << 8));
468 *(out++) = s;
469 in += 3;
473 static void S24LDecode( void *outp, const uint8_t *in, unsigned samples )
475 uint32_t *out = outp;
477 for( size_t i = 0; i < samples; i++ )
479 uint32_t s = ((in[2] << 24) | (in[1] << 16) | (in[0] << 8));
480 *(out++) = s;
481 in += 3;
485 static void S24B32Decode( void *outp, const uint8_t *in, unsigned samples )
487 uint32_t *out = outp;
489 for( size_t i = 0; i < samples; i++ )
491 *(out++) = GetDWBE( in ) << 8;
492 in += 4;
496 static void S24L32Decode( void *outp, const uint8_t *in, unsigned samples )
498 uint32_t *out = outp;
500 for( size_t i = 0; i < samples; i++ )
502 *(out++) = GetDWLE( in ) << 8;
503 in += 4;
507 static void U32BDecode( void *outp, const uint8_t *in, unsigned samples )
509 uint32_t *out = outp;
511 for( size_t i = 0; i < samples; i++ )
513 *(out++) = GetDWBE( in ) - 0x80000000;
514 in += 4;
518 static void U32LDecode( void *outp, const uint8_t *in, unsigned samples )
520 uint32_t *out = outp;
522 for( size_t i = 0; i < samples; i++ )
524 *(out++) = GetDWLE( in ) - 0x80000000;
525 in += 4;
529 static void S32IDecode( void *outp, const uint8_t *in, unsigned samples )
531 int32_t *out = outp;
533 for( size_t i = 0; i < samples; i++ )
535 #ifdef WORDS_BIGENDIAN
536 *(out++) = GetDWLE( in );
537 #else
538 *(out++) = GetDWBE( in );
539 #endif
540 in += 4;
544 static void F32NDecode( void *outp, const uint8_t *in, unsigned samples )
546 float *out = outp;
548 for( size_t i = 0; i < samples; i++ )
550 memcpy( out, in, sizeof(float) );
551 if( unlikely(!isfinite(*out)) )
552 *out = 0.f;
553 out++;
554 in += sizeof(float);
558 static void F32IDecode( void *outp, const uint8_t *in, unsigned samples )
560 float *out = outp;
562 for( size_t i = 0; i < samples; i++ )
564 union { float f; uint32_t u; } s;
566 #ifdef WORDS_BIGENDIAN
567 s.u = GetDWLE( in );
568 #else
569 s.u = GetDWBE( in );
570 #endif
571 if( unlikely(!isfinite(s.f)) )
572 s.f = 0.f;
573 *(out++) = s.f;
574 in += 4;
578 static void F64NDecode( void *outp, const uint8_t *in, unsigned samples )
580 double *out = outp;
582 for( size_t i = 0; i < samples; i++ )
584 memcpy( out, in, sizeof(double) );
585 if( unlikely(!isfinite( *out )) )
586 *out = 0.;
587 out++;
588 in += sizeof(double);
592 static void F64IDecode( void *outp, const uint8_t *in, unsigned samples )
594 double *out = outp;
596 for( size_t i = 0; i < samples; i++ )
598 union { double d; uint64_t u; } s;
600 #ifdef WORDS_BIGENDIAN
601 s.u = GetQWLE( in );
602 #else
603 s.u = GetQWBE( in );
604 #endif
605 if( unlikely(!isfinite( s.d )) )
606 s.d = 0.;
607 *(out++) = s.d;
608 in += 8;
612 static int16_t dat12tos16( uint_fast16_t y )
614 static const uint16_t diff[16] = {
615 0x0000, 0x0000, 0x0100, 0x0200, 0x0300, 0x0400, 0x0500, 0x0600,
616 0x0A00, 0x0B00, 0x0C00, 0x0D00, 0x0E00, 0x0F00, 0x1000, 0x1000 };
617 static const uint8_t shift[16] = {
618 0, 0, 1, 2, 3, 4, 5, 6, 6, 5, 4, 3, 2, 1, 0, 0 };
620 assert(y < 0x1000);
622 int d = y >> 8;
623 return (y - diff[d]) << shift[d];
626 static void DAT12Decode( void *outp, const uint8_t *in, unsigned samples )
628 int32_t *out = outp;
630 while( samples >= 2 )
632 *(out++) = dat12tos16(U16_AT(in) >> 4);
633 *(out++) = dat12tos16(U16_AT(in + 1) & ~0xF000);
634 in += 3;
635 samples -= 2;
638 if( samples )
639 *(out++) = dat12tos16(U16_AT(in) >> 4);
642 /*****************************************************************************
643 * DecoderClose: decoder destruction
644 *****************************************************************************/
645 static void DecoderClose( vlc_object_t *p_this )
647 decoder_t *p_dec = (decoder_t *)p_this;
649 free( p_dec->p_sys );
652 #ifdef ENABLE_SOUT
653 /* NOTE: Output buffers are always aligned since they are allocated by the araw plugin.
654 * Contrary to the decoder, the encoder can also assume that input buffers are aligned,
655 * since decoded audio blocks must always be aligned. */
657 static void U16IEncode( void *outp, const uint8_t *inp, unsigned samples )
659 const uint16_t *in = (const uint16_t *)inp;
660 uint16_t *out = outp;
662 for( size_t i = 0; i < samples; i++ )
663 *(out++) = bswap16( *(in++) + 0x8000 );
666 static void U16NEncode( void *outp, const uint8_t *inp, unsigned samples )
668 const uint16_t *in = (const uint16_t *)inp;
669 uint16_t *out = outp;
671 for( size_t i = 0; i < samples; i++ )
672 *(out++) = *(in++) + 0x8000;
675 static void U24BEncode( void *outp, const uint8_t *inp, unsigned samples )
677 const uint32_t *in = (const uint32_t *)inp;
678 uint8_t *out = outp;
680 for( size_t i = 0; i < samples; i++ )
682 uint32_t s = *(in++);
683 *(out++) = (s >> 24) + 0x80;
684 *(out++) = (s >> 16);
685 *(out++) = (s >> 8);
689 static void U24LEncode( void *outp, const uint8_t *inp, unsigned samples )
691 const uint32_t *in = (const uint32_t *)inp;
692 uint8_t *out = outp;
694 for( size_t i = 0; i < samples; i++ )
696 uint32_t s = *(in++);
697 *(out++) = (s >> 8);
698 *(out++) = (s >> 16);
699 *(out++) = (s >> 24) + 0x80;
703 static void S24BEncode( void *outp, const uint8_t *inp, unsigned samples )
705 const uint32_t *in = (const uint32_t *)inp;
706 uint8_t *out = outp;
708 for( size_t i = 0; i < samples; i++ )
710 uint32_t s = *(in++);
711 *(out++) = (s >> 24);
712 *(out++) = (s >> 16);
713 *(out++) = (s >> 8);
717 static void S24LEncode( void *outp, const uint8_t *inp, unsigned samples )
719 const uint32_t *in = (const uint32_t *)inp;
720 uint8_t *out = outp;
722 for( size_t i = 0; i < samples; i++ )
724 uint32_t s = *(in++);
725 *(out++) = (s >> 8);
726 *(out++) = (s >> 16);
727 *(out++) = (s >> 24);
731 static void U32IEncode( void *outp, const uint8_t *inp, unsigned samples )
733 const uint32_t *in = (const uint32_t *)inp;
734 uint32_t *out = outp;
736 for( size_t i = 0; i < samples; i++ )
737 *(out++) = bswap32( *(in++) + 0x80000000 );
740 static void U32NEncode( void *outp, const uint8_t *inp, unsigned samples )
742 const uint32_t *in = (const uint32_t *)inp;
743 uint32_t *out = outp;
745 for( size_t i = 0; i < samples; i++ )
746 *(out++) = *(in++) + 0x80000000;
749 static void S32IEncode( void *outp, const uint8_t *inp, unsigned samples )
751 const int32_t *in = (const int32_t *)inp;
752 int32_t *out = outp;
754 for( size_t i = 0; i < samples; i++ )
755 *(out++) = bswap32( *(in++) );
758 static void F32IEncode( void *outp, const uint8_t *inp, unsigned samples )
760 const float *in = (const float *)inp;
761 uint8_t *out = outp;
763 for( size_t i = 0; i < samples; i++ )
765 union { float f; uint32_t u; char b[4]; } s;
767 s.f = *(in++);
768 s.u = bswap32( s.u );
769 memcpy( out, s.b, 4 );
770 out += 4;
774 static void F64IEncode( void *outp, const uint8_t *inp, unsigned samples )
776 const double *in = (const double *)inp;
777 uint8_t *out = outp;
779 for( size_t i = 0; i < samples; i++ )
781 union { double d; uint64_t u; char b[8]; } s;
783 s.d = *(in++);
784 s.u = bswap64( s.u );
785 memcpy( out, s.b, 8 );
786 out += 8;
790 static block_t *Encode( encoder_t *enc, block_t *in )
792 if( in == NULL )
793 return NULL;
795 block_t *out = block_Alloc( in->i_nb_samples
796 * enc->fmt_out.audio.i_bytes_per_frame );
797 if( unlikely(out == NULL) )
798 return NULL;
800 out->i_flags = in->i_flags;
801 out->i_nb_samples = in->i_nb_samples;
802 out->i_dts = in->i_dts;
803 out->i_pts = in->i_pts;
804 out->i_length = in->i_length;
806 void (*encode)(void *, const uint8_t *, unsigned) = (void *)enc->p_sys;
807 if( encode != NULL )
808 encode( out->p_buffer, in->p_buffer, in->i_nb_samples
809 * enc->fmt_out.audio.i_channels );
810 else {
811 assert( out->i_buffer >= in->i_buffer );
812 memcpy( out->p_buffer, in->p_buffer, in->i_buffer );
814 return out;
818 * Probes the PCM audio encoder.
820 static int EncoderOpen( vlc_object_t *p_this )
822 encoder_t *p_enc = (encoder_t *)p_this;
823 void (*encode)(void *, const uint8_t *, unsigned) = NULL;
825 switch( p_enc->fmt_out.i_codec )
827 case VLC_CODEC_S8:
828 encode = S8Decode;
829 /* fall through */
830 case VLC_CODEC_U8:
831 p_enc->fmt_in.i_codec = VLC_CODEC_U8;
832 p_enc->fmt_out.audio.i_bitspersample = 8;
833 break;
834 case VLC_CODEC_U16I:
835 encode = U16IEncode;
836 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
837 p_enc->fmt_out.audio.i_bitspersample = 16;
838 break;
839 case VLC_CODEC_U16N:
840 encode = U16NEncode;
841 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
842 p_enc->fmt_out.audio.i_bitspersample = 16;
843 break;
844 case VLC_CODEC_S16I:
845 encode = S16IDecode;
846 /* fall through */
847 case VLC_CODEC_S16N:
848 p_enc->fmt_in.i_codec = VLC_CODEC_S16N;
849 p_enc->fmt_out.audio.i_bitspersample = 16;
850 break;
851 case VLC_CODEC_U24B:
852 encode = U24BEncode;
853 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
854 p_enc->fmt_out.audio.i_bitspersample = 24;
855 break;
856 case VLC_CODEC_U24L:
857 encode = U24LEncode;
858 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
859 p_enc->fmt_out.audio.i_bitspersample = 24;
860 break;
861 case VLC_CODEC_S24B:
862 encode = S24BEncode;
863 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
864 p_enc->fmt_out.audio.i_bitspersample = 24;
865 break;
866 case VLC_CODEC_S24L:
867 encode = S24LEncode;
868 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
869 p_enc->fmt_out.audio.i_bitspersample = 24;
870 break;
871 case VLC_CODEC_U32I:
872 encode = U32IEncode;
873 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
874 p_enc->fmt_out.audio.i_bitspersample = 32;
875 break;
876 case VLC_CODEC_U32N:
877 encode = U32NEncode;
878 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
879 p_enc->fmt_out.audio.i_bitspersample = 32;
880 break;
881 case VLC_CODEC_S32I:
882 encode = S32IEncode;
883 /* fall through */
884 case VLC_CODEC_S32N:
885 p_enc->fmt_in.i_codec = VLC_CODEC_S32N;
886 p_enc->fmt_out.audio.i_bitspersample = 32;
887 break;
888 #ifdef WORDS_BIGENDIAN
889 case VLC_CODEC_F32L:
890 #else
891 case VLC_CODEC_F32B:
892 #endif
893 encode = F32IEncode;
894 /* fall through */
895 case VLC_CODEC_FL32:
896 p_enc->fmt_in.i_codec = VLC_CODEC_FL32;
897 p_enc->fmt_out.audio.i_bitspersample = 32;
898 break;
899 #ifdef WORDS_BIGENDIAN
900 case VLC_CODEC_F64L:
901 #else
902 case VLC_CODEC_F64B:
903 #endif
904 encode = F64IEncode;
905 /* fall through */
906 case VLC_CODEC_FL64:
907 p_enc->fmt_in.i_codec = VLC_CODEC_FL64;
908 p_enc->fmt_out.audio.i_bitspersample = 64;
909 break;
910 default:
911 return VLC_EGENERIC;
914 p_enc->p_sys = (void *)encode;
915 p_enc->pf_encode_audio = Encode;
916 p_enc->fmt_out.audio.i_bytes_per_frame =
917 (p_enc->fmt_out.audio.i_bitspersample / 8) *
918 p_enc->fmt_in.audio.i_channels;
919 p_enc->fmt_out.i_bitrate =
920 p_enc->fmt_in.audio.i_channels *
921 p_enc->fmt_in.audio.i_rate *
922 p_enc->fmt_out.audio.i_bitspersample;
924 msg_Dbg( p_enc, "samplerate:%dHz channels:%d bits/sample:%d",
925 p_enc->fmt_out.audio.i_rate, p_enc->fmt_out.audio.i_channels,
926 p_enc->fmt_out.audio.i_bitspersample );
928 return VLC_SUCCESS;
930 #endif /* ENABLE_SOUT */