]> git.sesse.net Git - vlc/blob - modules/codec/araw.c
* araw: mhh, aout_buffer_t.i_nb_samples is samples _per_ channels...
[vlc] / modules / codec / araw.c
1 /*****************************************************************************
2  * araw.c: Pseudo audio decoder; for raw pcm data
3  *****************************************************************************
4  * Copyright (C) 2001, 2002 VideoLAN
5  * $Id: araw.c,v 1.20 2003/11/01 06:56:29 fenrir Exp $
6  *
7  * Authors: Laurent Aimar <fenrir@via.ecp.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 2 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program; if not, write to the Free Software
21  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111, USA.
22  *****************************************************************************/
23
24 /*****************************************************************************
25  * Preamble
26  *****************************************************************************/
27 #include <stdlib.h>                                      /* malloc(), free() */
28 #include <vlc/vlc.h>
29 #include <vlc/aout.h>
30 #include <vlc/decoder.h>
31 #include <vlc/input.h>
32
33 #include <vlc/sout.h>
34 #include "aout_internal.h"
35
36 #include "codecs.h"
37
38 /*****************************************************************************
39  * Module descriptor
40  *****************************************************************************/
41 static int  DecoderOpen    ( vlc_object_t * );
42
43 static int  EncoderOpen  ( vlc_object_t *p_this );
44 static void EncoderClose ( vlc_object_t *p_this );
45
46 vlc_module_begin();
47     /* audio decoder module */
48     set_description( _("Pseudo Raw/Log Audio decoder") );
49     set_capability( "decoder", 50 );
50     set_callbacks( DecoderOpen, NULL );
51
52     /* audio encoder submodule */
53     add_submodule();
54     set_description( _("Raw audio encoder") );
55     set_capability( "audio encoder", 10 );
56     set_callbacks( EncoderOpen, EncoderClose );
57 vlc_module_end();
58
59
60 /*****************************************************************************
61  * Local prototypes
62  *****************************************************************************/
63
64 typedef struct
65 {
66     WAVEFORMATEX    *p_wf;
67
68     /* Input properties */
69     decoder_fifo_t *p_fifo;
70     int16_t        *p_logtos16;  // used with m/alaw to int16_t
71
72     /* Output properties */
73     aout_instance_t *   p_aout;       /* opaque */
74     aout_input_t *      p_aout_input; /* opaque */
75     audio_sample_format_t output_format;
76
77     audio_date_t        date;
78     mtime_t             pts;
79
80 } adec_thread_t;
81
82
83 static int  RunDecoder     ( decoder_fifo_t * );
84 static int  InitThread     ( adec_thread_t * );
85 static void DecodeThread   ( adec_thread_t * );
86 static void EndThread      ( adec_thread_t * );
87
88
89 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf );
90
91 /*****************************************************************************
92  * DecoderOpen: probe the decoder and return score
93  *****************************************************************************
94  * Tries to launch a decoder and return score so that the interface is able
95  * to choose.
96  *****************************************************************************/
97 static int DecoderOpen( vlc_object_t *p_this )
98 {
99     decoder_t *p_dec = (decoder_t*)p_this;
100
101     switch( p_dec->p_fifo->i_fourcc )
102     {
103         case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
104         case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
105         case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
106
107         case VLC_FOURCC('a','l','a','w'):
108         case VLC_FOURCC('u','l','a','w'):
109             p_dec->pf_run = RunDecoder;
110             return VLC_SUCCESS;
111
112         default:
113             return VLC_EGENERIC;
114     }
115 }
116
117 static int pi_channels_maps[6] =
118 {
119     0,
120     AOUT_CHAN_CENTER,
121     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
122     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
123     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
124     AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
125      | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
126 };
127
128 static int16_t ulawtos16[256] =
129 {
130     -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
131     -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
132     -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
133     -11900, -11388, -10876, -10364,  -9852,  -9340,  -8828,  -8316,
134      -7932,  -7676,  -7420,  -7164,  -6908,  -6652,  -6396,  -6140,
135      -5884,  -5628,  -5372,  -5116,  -4860,  -4604,  -4348,  -4092,
136      -3900,  -3772,  -3644,  -3516,  -3388,  -3260,  -3132,  -3004,
137      -2876,  -2748,  -2620,  -2492,  -2364,  -2236,  -2108,  -1980,
138      -1884,  -1820,  -1756,  -1692,  -1628,  -1564,  -1500,  -1436,
139      -1372,  -1308,  -1244,  -1180,  -1116,  -1052,   -988,   -924,
140       -876,   -844,   -812,   -780,   -748,   -716,   -684,   -652,
141       -620,   -588,   -556,   -524,   -492,   -460,   -428,   -396,
142       -372,   -356,   -340,   -324,   -308,   -292,   -276,   -260,
143       -244,   -228,   -212,   -196,   -180,   -164,   -148,   -132,
144       -120,   -112,   -104,    -96,    -88,    -80,    -72,    -64,
145        -56,    -48,    -40,    -32,    -24,    -16,     -8,      0,
146      32124,  31100,  30076,  29052,  28028,  27004,  25980,  24956,
147      23932,  22908,  21884,  20860,  19836,  18812,  17788,  16764,
148      15996,  15484,  14972,  14460,  13948,  13436,  12924,  12412,
149      11900,  11388,  10876,  10364,   9852,   9340,   8828,   8316,
150       7932,   7676,   7420,   7164,   6908,   6652,   6396,   6140,
151       5884,   5628,   5372,   5116,   4860,   4604,   4348,   4092,
152       3900,   3772,   3644,   3516,   3388,   3260,   3132,   3004,
153       2876,   2748,   2620,   2492,   2364,   2236,   2108,   1980,
154       1884,   1820,   1756,   1692,   1628,   1564,   1500,   1436,
155       1372,   1308,   1244,   1180,   1116,   1052,    988,    924,
156        876,    844,    812,    780,    748,    716,    684,    652,
157        620,    588,    556,    524,    492,    460,    428,    396,
158        372,    356,    340,    324,    308,    292,    276,    260,
159        244,    228,    212,    196,    180,    164,    148,    132,
160        120,    112,    104,     96,     88,     80,     72,     64,
161         56,     48,     40,     32,     24,     16,      8,      0
162 };
163
164 static int16_t alawtos16[256] =
165 {
166      -5504,  -5248,  -6016,  -5760,  -4480,  -4224,  -4992,  -4736,
167      -7552,  -7296,  -8064,  -7808,  -6528,  -6272,  -7040,  -6784,
168      -2752,  -2624,  -3008,  -2880,  -2240,  -2112,  -2496,  -2368,
169      -3776,  -3648,  -4032,  -3904,  -3264,  -3136,  -3520,  -3392,
170     -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
171     -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
172     -11008, -10496, -12032, -11520,  -8960,  -8448,  -9984,  -9472,
173     -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
174       -344,   -328,   -376,   -360,   -280,   -264,   -312,   -296,
175       -472,   -456,   -504,   -488,   -408,   -392,   -440,   -424,
176        -88,    -72,   -120,   -104,    -24,     -8,    -56,    -40,
177       -216,   -200,   -248,   -232,   -152,   -136,   -184,   -168,
178      -1376,  -1312,  -1504,  -1440,  -1120,  -1056,  -1248,  -1184,
179      -1888,  -1824,  -2016,  -1952,  -1632,  -1568,  -1760,  -1696,
180       -688,   -656,   -752,   -720,   -560,   -528,   -624,   -592,
181       -944,   -912,  -1008,   -976,   -816,   -784,   -880,   -848,
182       5504,   5248,   6016,   5760,   4480,   4224,   4992,   4736,
183       7552,   7296,   8064,   7808,   6528,   6272,   7040,   6784,
184       2752,   2624,   3008,   2880,   2240,   2112,   2496,   2368,
185       3776,   3648,   4032,   3904,   3264,   3136,   3520,   3392,
186      22016,  20992,  24064,  23040,  17920,  16896,  19968,  18944,
187      30208,  29184,  32256,  31232,  26112,  25088,  28160,  27136,
188      11008,  10496,  12032,  11520,   8960,   8448,   9984,   9472,
189      15104,  14592,  16128,  15616,  13056,  12544,  14080,  13568,
190        344,    328,    376,    360,    280,    264,    312,    296,
191        472,    456,    504,    488,    408,    392,    440,    424,
192         88,     72,    120,    104,     24,      8,     56,     40,
193        216,    200,    248,    232,    152,    136,    184,    168,
194       1376,   1312,   1504,   1440,   1120,   1056,   1248,   1184,
195       1888,   1824,   2016,   1952,   1632,   1568,   1760,   1696,
196        688,    656,    752,    720,    560,    528,    624,    592,
197        944,    912,   1008,    976,    816,    784,    880,    848
198 };
199
200 /*****************************************************************************
201  * RunDecoder: this function is called just after the thread is created
202  *****************************************************************************/
203 static int RunDecoder( decoder_fifo_t *p_fifo )
204 {
205     adec_thread_t *p_adec;
206     int b_error;
207
208     if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
209     {
210         msg_Err( p_fifo, "out of memory" );
211         DecoderError( p_fifo );
212         return( -1 );
213     }
214     memset( p_adec, 0, sizeof( adec_thread_t ) );
215
216     p_adec->p_fifo = p_fifo;
217
218     if( InitThread( p_adec ) != 0 )
219     {
220         DecoderError( p_fifo );
221         return( -1 );
222     }
223
224     while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
225     {
226         DecodeThread( p_adec );
227     }
228
229
230     if( ( b_error = p_adec->p_fifo->b_error ) )
231     {
232         DecoderError( p_adec->p_fifo );
233     }
234
235     EndThread( p_adec );
236     if( b_error )
237     {
238         return( -1 );
239     }
240
241     return( 0 );
242 }
243
244
245 #define FREE( p ) if( p ) free( p ); p = NULL
246
247 /*****************************************************************************
248  * InitThread: initialize data before entering main loop
249  *****************************************************************************/
250 static int InitThread( adec_thread_t * p_adec )
251 {
252     if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
253         == NULL )
254     {
255         msg_Err( p_adec->p_fifo, "unknown raw format" );
256         return( -1 );
257     }
258
259     /* fixing some values */
260     if( ( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_PCM ||
261           p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )&&
262         !p_adec->p_wf->nBlockAlign )
263     {
264         p_adec->p_wf->nBlockAlign =
265             p_adec->p_wf->nChannels *
266                 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
267     }
268
269     msg_Dbg( p_adec->p_fifo,
270              "raw format: samplerate:%dHz channels:%d bits/sample:%d "
271              "blockalign:%d",
272              p_adec->p_wf->nSamplesPerSec,
273              p_adec->p_wf->nChannels,
274              p_adec->p_wf->wBitsPerSample,
275              p_adec->p_wf->nBlockAlign );
276
277     /* Initialize the thread properties */
278     p_adec->p_logtos16 = NULL;
279     if( p_adec->p_wf->wFormatTag  == WAVE_FORMAT_IEEE_FLOAT )
280     {
281         switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
282         {
283             case( 4 ):
284                 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
285                 break;
286             case( 8 ):
287                 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
288                 break;
289             default:
290                 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
291                 return( -1 );
292         }
293     }
294     else
295     {
296         if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
297         {
298             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
299             {
300                 case( 1 ):
301                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
302                     break;
303                 case( 2 ):
304                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
305                     break;
306                 case( 3 ):
307                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
308                     break;
309                 case( 4 ):
310                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
311                     break;
312                 default:
313                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
314                     return( -1 );
315             }
316         }
317         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
318         {
319             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
320             {
321                 case( 1 ):
322                     p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
323                     break;
324                 case( 2 ):
325                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
326                     break;
327                 case( 3 ):
328                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
329                     break;
330                 case( 4 ):
331                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
332                     break;
333                 default:
334                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
335                     return( -1 );
336             }
337         }
338         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
339         {
340             switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
341             {
342                 case( 1 ):
343                     p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
344                     break;
345                 case( 2 ):
346                     p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
347                     break;
348                 case( 3 ):
349                     p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
350                     break;
351                 case( 4 ):
352                     p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
353                     break;
354                 default:
355                     msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
356                     return( -1 );
357             }
358         }
359         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
360         {
361             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
362             p_adec->p_logtos16  = alawtos16;
363         }
364         else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
365         {
366             p_adec->output_format.i_format = AOUT_FMT_S16_NE;
367             p_adec->p_logtos16  = ulawtos16;
368         }
369     }
370     p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
371
372     if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
373     {
374         msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
375         return( -1 );
376     }
377
378     p_adec->output_format.i_physical_channels =
379             p_adec->output_format.i_original_channels =
380             pi_channels_maps[p_adec->p_wf->nChannels];
381     p_adec->p_aout = NULL;
382     p_adec->p_aout_input = NULL;
383
384     /* **** Create a new audio output **** */
385     aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
386     p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
387                                         &p_adec->p_aout,
388                                         &p_adec->output_format );
389     if( !p_adec->p_aout_input )
390     {
391         msg_Err( p_adec->p_fifo, "cannot create aout" );
392         return( -1 );
393     }
394
395     return( 0 );
396 }
397
398 static void GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
399 {
400     int i_copy;
401     int i_count;
402
403     data_packet_t   *p_data;
404
405     i_count = 0;
406     p_data = p_pes->p_first;
407     while( p_data != NULL && i_count < i_max )
408     {
409
410         i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
411                         i_max - i_count );
412
413         if( i_copy > 0 )
414         {
415             memcpy( p_buf,
416                     p_data->p_payload_start,
417                     i_copy );
418         }
419
420         p_data = p_data->p_next;
421         i_count += i_copy;
422         p_buf   += i_copy;
423     }
424
425     if( i_count < i_max )
426     {
427         memset( p_buf, 0, i_max - i_count );
428     }
429 }
430
431 /*****************************************************************************
432  * DecodeThread: decodes a frame
433  *****************************************************************************/
434 static void DecodeThread( adec_thread_t *p_adec )
435 {
436     aout_buffer_t   *p_aout_buffer;
437     int             i_samples; // per channels
438     int             i_size;
439     uint8_t         *p_data, *p;
440     pes_packet_t    *p_pes;
441
442     /* **** get samples count **** */
443     input_ExtractPES( p_adec->p_fifo, &p_pes );
444     if( !p_pes )
445     {
446         p_adec->p_fifo->b_error = 1;
447         return;
448     }
449     i_size = p_pes->i_pes_size;
450
451     if( p_adec->p_wf->nBlockAlign > 0 )
452     {
453         i_size -= i_size % p_adec->p_wf->nBlockAlign;
454     }
455     if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
456     {
457         input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
458         return;
459     }
460
461     i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
462                 p_adec->p_wf->nChannels;
463
464     p_adec->pts = p_pes->i_pts;
465
466     /* **** Now we can output these samples **** */
467
468     if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
469     {
470         aout_DateSet( &p_adec->date, p_adec->pts );
471     }
472     else if( !aout_DateGet( &p_adec->date ) )
473     {
474         return;
475     }
476
477     /* gather data */
478     p = p_data = malloc( i_size );
479     GetPESData( p_data, i_size, p_pes );
480
481     while( i_samples > 0 )
482     {
483         int i_copy;
484
485         i_copy = __MIN( i_samples, 1024 );
486         p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
487                                            p_adec->p_aout_input,
488                                            i_copy );
489         if( !p_aout_buffer )
490         {
491             msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
492             p_adec->p_fifo->b_error = 1;
493
494             free( p_data );
495             return;
496         }
497
498         p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
499         p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
500                                                       i_copy );
501
502         if( p_adec->p_logtos16 )
503         {
504             int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
505
506             unsigned int     i;
507
508             for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
509             {
510                 *s++ = p_adec->p_logtos16[*p++];
511             }
512         }
513         else
514         {
515             memcpy( p_aout_buffer->p_buffer, p,
516                     p_aout_buffer->i_nb_bytes );
517
518             p += p_aout_buffer->i_nb_bytes;
519         }
520
521         aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
522
523         i_samples -= i_copy;
524     }
525
526     free( p_data );
527     input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
528 }
529
530 /*****************************************************************************
531  * EndThread : faad decoder thread destruction
532  *****************************************************************************/
533 static void EndThread (adec_thread_t *p_adec)
534 {
535     if( p_adec->p_aout_input )
536     {
537         aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
538     }
539
540     msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );
541
542     free( p_adec );
543 }
544
545 /*****************************************************************************
546  * EncoderOpen:
547  *****************************************************************************/
548 static int  EncoderOpen  ( vlc_object_t *p_this )
549 {
550     encoder_t *p_enc = (encoder_t *)p_this;
551
552     if( p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'b' ) &&
553         p_enc->format.audio.i_format != VLC_FOURCC( 's', '1', '6', 'l' ) )
554     {
555         msg_Warn( p_enc, "unhandled input format" );
556         return VLC_EGENERIC;
557     }
558
559     switch( p_enc->i_fourcc )
560     {
561         case VLC_FOURCC( 's', '1', '6', 'b' ):
562         case VLC_FOURCC( 's', '1', '6', 'l' ):
563         case VLC_FOURCC( 'u', '8', ' ', ' ' ):
564         case VLC_FOURCC( 's', '8', ' ', ' ' ):
565 #if 0
566         -> could be easyly done with table look up
567         case VLC_FOURCC( 'a', 'l', 'a', 'w' ):
568         case VLC_FOURCC( 'u', 'l', 'a', 'w' ):
569 #endif
570             break;
571         default:
572             return VLC_EGENERIC;
573     }
574
575     p_enc->p_sys = NULL;
576     p_enc->pf_header = NULL;
577     p_enc->pf_encode_audio = EncoderEncode;
578     p_enc->pf_encode_video = NULL;
579     p_enc->i_extra_data = 0;
580     p_enc->p_extra_data = NULL;
581
582     return VLC_SUCCESS;
583 }
584
585 /*****************************************************************************
586  * EncoderClose:
587  *****************************************************************************/
588 static void EncoderClose ( vlc_object_t *p_this )
589 {
590     return;
591 }
592
593 /*****************************************************************************
594  * EncoderEncode:
595  *****************************************************************************/
596 static block_t *EncoderEncode( encoder_t *p_enc, aout_buffer_t *p_aout_buf )
597 {
598     block_t *p_block = NULL;
599     unsigned int i;
600
601     if( p_enc->i_fourcc == p_enc->format.audio.i_format )
602     {
603         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
604         {
605             memcpy( p_block->p_buffer, p_aout_buf->p_buffer, p_aout_buf->i_nb_bytes );
606         }
607     }
608     else if( p_enc->i_fourcc == VLC_FOURCC( 'u', '8', ' ', ' ' ) )
609     {
610         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
611         {
612             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
613             int8_t  *p_src = (int8_t*) p_aout_buf->p_buffer;
614
615             if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
616             {
617                 p_src++;
618             }
619
620             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
621             {
622                 *p_dst++ = *p_src + 128; p_src += 2;
623             }
624         }
625     }
626     else if( p_enc->i_fourcc == VLC_FOURCC( 's', '8', ' ', ' ' ) )
627     {
628         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes / 2 ) ) )
629         {
630             int8_t *p_dst = (int8_t*)p_block->p_buffer;
631             int8_t *p_src = (int8_t*)p_aout_buf->p_buffer;
632
633             if( p_enc->format.audio.i_format == VLC_FOURCC( 's', '1', '6', 'l' ) )
634             {
635                 p_src++;
636             }
637
638             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
639             {
640                 *p_dst++ = *p_src; p_src += 2;
641             }
642         }
643     }
644     else
645     {
646         /* endian swapping */
647         if( ( p_block = block_New( p_enc, p_aout_buf->i_nb_bytes ) ) )
648         {
649             uint8_t *p_dst = (uint8_t*)p_block->p_buffer;
650             uint8_t *p_src = (uint8_t*)p_aout_buf->p_buffer;
651
652             for( i = 0; i < p_aout_buf->i_nb_bytes / 2; i++ )
653             {
654                 p_dst[0] = p_src[1];
655                 p_dst[1] = p_src[0];
656
657                 p_dst += 2;
658                 p_src += 2;
659             }
660         }
661     }
662
663     if( p_block )
664     {
665         p_block->i_dts = p_block->i_pts = p_aout_buf->start_date;
666         p_block->i_length = (int64_t)p_aout_buf->i_nb_samples * (int64_t)1000000 /
667                             p_enc->format.audio.i_rate;
668     }
669
670     return p_block;
671 }
672
673