1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: araw.c,v 1.15 2003/05/17 20:30:31 gbazin Exp $
7 * Authors: Laurent Aimar <fenrir@via.ecp.fr>
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.
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.
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 *****************************************************************************/
24 /*****************************************************************************
26 *****************************************************************************/
29 #include <vlc/decoder.h>
30 #include <vlc/input.h>
32 #include <stdlib.h> /* malloc(), free() */
33 #include <string.h> /* strdup() */
35 /*****************************************************************************
37 *****************************************************************************/
39 typedef struct adec_thread_s
43 /* Input properties */
44 decoder_fifo_t *p_fifo;
45 int16_t *p_logtos16; // used with m/alaw to s16
47 /* Output properties */
48 aout_instance_t * p_aout; /* opaque */
49 aout_input_t * p_aout_input; /* opaque */
50 audio_sample_format_t output_format;
57 static int OpenDecoder ( vlc_object_t * );
59 static int RunDecoder ( decoder_fifo_t * );
60 static int InitThread ( adec_thread_t * );
61 static void DecodeThread ( adec_thread_t * );
62 static void EndThread ( adec_thread_t * );
64 /*****************************************************************************
66 *****************************************************************************/
69 set_description( _("Pseudo Raw/Log Audio decoder") );
70 set_capability( "decoder", 50 );
71 set_callbacks( OpenDecoder, NULL );
75 /*****************************************************************************
76 * OpenDecoder: probe the decoder and return score
77 *****************************************************************************
78 * Tries to launch a decoder and return score so that the interface is able
80 *****************************************************************************/
81 static int OpenDecoder( vlc_object_t *p_this )
83 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
85 switch( p_fifo->i_fourcc )
87 case VLC_FOURCC('a','r','a','w'): /* from wav/avi/asf file */
88 case VLC_FOURCC('t','w','o','s'): /* _signed_ big endian samples (mov)*/
89 case VLC_FOURCC('s','o','w','t'): /* _signed_ little endian samples (mov)*/
91 case VLC_FOURCC('a','l','a','w'):
92 case VLC_FOURCC('u','l','a','w'):
93 p_fifo->pf_run = RunDecoder;
102 static int pi_channels_maps[6] =
106 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
107 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
108 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
109 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
110 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
113 static int16_t ulawtos16[256] =
115 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
116 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
117 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
118 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
119 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
120 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
121 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
122 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
123 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
124 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
125 -876, -844, -812, -780, -748, -716, -684, -652,
126 -620, -588, -556, -524, -492, -460, -428, -396,
127 -372, -356, -340, -324, -308, -292, -276, -260,
128 -244, -228, -212, -196, -180, -164, -148, -132,
129 -120, -112, -104, -96, -88, -80, -72, -64,
130 -56, -48, -40, -32, -24, -16, -8, 0,
131 32124, 31100, 30076, 29052, 28028, 27004, 25980, 24956,
132 23932, 22908, 21884, 20860, 19836, 18812, 17788, 16764,
133 15996, 15484, 14972, 14460, 13948, 13436, 12924, 12412,
134 11900, 11388, 10876, 10364, 9852, 9340, 8828, 8316,
135 7932, 7676, 7420, 7164, 6908, 6652, 6396, 6140,
136 5884, 5628, 5372, 5116, 4860, 4604, 4348, 4092,
137 3900, 3772, 3644, 3516, 3388, 3260, 3132, 3004,
138 2876, 2748, 2620, 2492, 2364, 2236, 2108, 1980,
139 1884, 1820, 1756, 1692, 1628, 1564, 1500, 1436,
140 1372, 1308, 1244, 1180, 1116, 1052, 988, 924,
141 876, 844, 812, 780, 748, 716, 684, 652,
142 620, 588, 556, 524, 492, 460, 428, 396,
143 372, 356, 340, 324, 308, 292, 276, 260,
144 244, 228, 212, 196, 180, 164, 148, 132,
145 120, 112, 104, 96, 88, 80, 72, 64,
146 56, 48, 40, 32, 24, 16, 8, 0
149 static int16_t alawtos16[256] =
151 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
152 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
153 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
154 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
155 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
156 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
157 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
158 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
159 -344, -328, -376, -360, -280, -264, -312, -296,
160 -472, -456, -504, -488, -408, -392, -440, -424,
161 -88, -72, -120, -104, -24, -8, -56, -40,
162 -216, -200, -248, -232, -152, -136, -184, -168,
163 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
164 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
165 -688, -656, -752, -720, -560, -528, -624, -592,
166 -944, -912, -1008, -976, -816, -784, -880, -848,
167 5504, 5248, 6016, 5760, 4480, 4224, 4992, 4736,
168 7552, 7296, 8064, 7808, 6528, 6272, 7040, 6784,
169 2752, 2624, 3008, 2880, 2240, 2112, 2496, 2368,
170 3776, 3648, 4032, 3904, 3264, 3136, 3520, 3392,
171 22016, 20992, 24064, 23040, 17920, 16896, 19968, 18944,
172 30208, 29184, 32256, 31232, 26112, 25088, 28160, 27136,
173 11008, 10496, 12032, 11520, 8960, 8448, 9984, 9472,
174 15104, 14592, 16128, 15616, 13056, 12544, 14080, 13568,
175 344, 328, 376, 360, 280, 264, 312, 296,
176 472, 456, 504, 488, 408, 392, 440, 424,
177 88, 72, 120, 104, 24, 8, 56, 40,
178 216, 200, 248, 232, 152, 136, 184, 168,
179 1376, 1312, 1504, 1440, 1120, 1056, 1248, 1184,
180 1888, 1824, 2016, 1952, 1632, 1568, 1760, 1696,
181 688, 656, 752, 720, 560, 528, 624, 592,
182 944, 912, 1008, 976, 816, 784, 880, 848
185 /*****************************************************************************
186 * RunDecoder: this function is called just after the thread is created
187 *****************************************************************************/
188 static int RunDecoder( decoder_fifo_t *p_fifo )
190 adec_thread_t *p_adec;
193 if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
195 msg_Err( p_fifo, "out of memory" );
196 DecoderError( p_fifo );
199 memset( p_adec, 0, sizeof( adec_thread_t ) );
201 p_adec->p_fifo = p_fifo;
203 if( InitThread( p_adec ) != 0 )
205 DecoderError( p_fifo );
209 while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
211 DecodeThread( p_adec );
215 if( ( b_error = p_adec->p_fifo->b_error ) )
217 DecoderError( p_adec->p_fifo );
230 #define FREE( p ) if( p ) free( p ); p = NULL
231 #define GetWLE( p ) \
232 ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
234 #define GetDWLE( p ) \
235 ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
236 ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
239 /*****************************************************************************
240 * InitThread: initialize data before entering main loop
241 *****************************************************************************/
242 static int InitThread( adec_thread_t * p_adec )
244 if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
247 msg_Err( p_adec->p_fifo, "unknown raw format" );
251 /* fixing some values */
252 if( ( p_adec->p_wf->wFormatTag == WAVE_FORMAT_PCM ||
253 p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )&&
254 !p_adec->p_wf->nBlockAlign )
256 p_adec->p_wf->nBlockAlign =
257 p_adec->p_wf->nChannels *
258 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
261 msg_Dbg( p_adec->p_fifo,
262 "raw format: samplerate:%dHz channels:%d bits/sample:%d "
264 p_adec->p_wf->nSamplesPerSec,
265 p_adec->p_wf->nChannels,
266 p_adec->p_wf->wBitsPerSample,
267 p_adec->p_wf->nBlockAlign );
269 /* Initialize the thread properties */
270 p_adec->p_logtos16 = NULL;
271 if( p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )
273 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
276 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
279 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
282 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
288 if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
290 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
293 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
296 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
299 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
302 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
305 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
309 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
311 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
314 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
317 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
320 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
323 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
326 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
330 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
332 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
335 p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
338 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
341 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
344 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
347 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
351 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
353 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
354 p_adec->p_logtos16 = alawtos16;
356 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
358 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
359 p_adec->p_logtos16 = ulawtos16;
362 p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
364 if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
366 msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
370 p_adec->output_format.i_physical_channels =
371 p_adec->output_format.i_original_channels =
372 pi_channels_maps[p_adec->p_wf->nChannels];
373 p_adec->p_aout = NULL;
374 p_adec->p_aout_input = NULL;
376 /* **** Create a new audio output **** */
377 aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
378 p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
380 &p_adec->output_format );
381 if( !p_adec->p_aout_input )
383 msg_Err( p_adec->p_fifo, "cannot create aout" );
390 static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
395 data_packet_t *p_data;
398 p_data = p_pes->p_first;
399 while( p_data != NULL && i_count < i_max )
402 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
408 p_data->p_payload_start,
412 p_data = p_data->p_next;
417 if( i_count < i_max )
419 memset( p_buf, 0, i_max - i_count );
423 /*****************************************************************************
424 * DecodeThread: decodes a frame
425 *****************************************************************************/
426 static void DecodeThread( adec_thread_t *p_adec )
428 aout_buffer_t *p_aout_buffer;
429 int i_samples; // per channels
434 /* **** get samples count **** */
435 input_ExtractPES( p_adec->p_fifo, &p_pes );
438 p_adec->p_fifo->b_error = 1;
441 i_size = p_pes->i_pes_size;
443 if( p_adec->p_wf->nBlockAlign > 0 )
445 i_size -= i_size % p_adec->p_wf->nBlockAlign;
447 if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
449 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
453 i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
454 p_adec->p_wf->nChannels;
456 p_adec->pts = p_pes->i_pts;
458 /* **** Now we can output these samples **** */
460 if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
462 aout_DateSet( &p_adec->date, p_adec->pts );
464 else if( !aout_DateGet( &p_adec->date ) )
470 p = p_data = malloc( i_size );
471 GetPESData( p_data, i_size, p_pes );
473 while( i_samples > 0 )
477 i_copy = __MIN( i_samples, 1024 );
478 p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
479 p_adec->p_aout_input,
483 msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
484 p_adec->p_fifo->b_error = 1;
490 p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
491 p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
494 if( p_adec->p_logtos16 )
496 int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
500 for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
502 *s++ = p_adec->p_logtos16[*p++];
507 memcpy( p_aout_buffer->p_buffer, p,
508 p_aout_buffer->i_nb_bytes );
510 p += p_aout_buffer->i_nb_bytes;
513 aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
519 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
522 /*****************************************************************************
523 * EndThread : faad decoder thread destruction
524 *****************************************************************************/
525 static void EndThread (adec_thread_t *p_adec)
527 if( p_adec->p_aout_input )
529 aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
532 msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );