1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: araw.c,v 1.16 2003/08/17 23:02:51 fenrir 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
232 /*****************************************************************************
233 * InitThread: initialize data before entering main loop
234 *****************************************************************************/
235 static int InitThread( adec_thread_t * p_adec )
237 if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
240 msg_Err( p_adec->p_fifo, "unknown raw format" );
244 /* fixing some values */
245 if( ( p_adec->p_wf->wFormatTag == WAVE_FORMAT_PCM ||
246 p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )&&
247 !p_adec->p_wf->nBlockAlign )
249 p_adec->p_wf->nBlockAlign =
250 p_adec->p_wf->nChannels *
251 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
254 msg_Dbg( p_adec->p_fifo,
255 "raw format: samplerate:%dHz channels:%d bits/sample:%d "
257 p_adec->p_wf->nSamplesPerSec,
258 p_adec->p_wf->nChannels,
259 p_adec->p_wf->wBitsPerSample,
260 p_adec->p_wf->nBlockAlign );
262 /* Initialize the thread properties */
263 p_adec->p_logtos16 = NULL;
264 if( p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )
266 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
269 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
272 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
275 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
281 if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
283 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
286 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
289 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
292 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
295 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
298 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
302 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
304 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
307 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
310 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
313 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
316 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
319 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
323 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
325 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
328 p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
331 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
334 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
337 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
340 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
344 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
346 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
347 p_adec->p_logtos16 = alawtos16;
349 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
351 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
352 p_adec->p_logtos16 = ulawtos16;
355 p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
357 if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
359 msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
363 p_adec->output_format.i_physical_channels =
364 p_adec->output_format.i_original_channels =
365 pi_channels_maps[p_adec->p_wf->nChannels];
366 p_adec->p_aout = NULL;
367 p_adec->p_aout_input = NULL;
369 /* **** Create a new audio output **** */
370 aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
371 p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
373 &p_adec->output_format );
374 if( !p_adec->p_aout_input )
376 msg_Err( p_adec->p_fifo, "cannot create aout" );
383 static void GetPESData( u8 *p_buf, int i_max, pes_packet_t *p_pes )
388 data_packet_t *p_data;
391 p_data = p_pes->p_first;
392 while( p_data != NULL && i_count < i_max )
395 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
401 p_data->p_payload_start,
405 p_data = p_data->p_next;
410 if( i_count < i_max )
412 memset( p_buf, 0, i_max - i_count );
416 /*****************************************************************************
417 * DecodeThread: decodes a frame
418 *****************************************************************************/
419 static void DecodeThread( adec_thread_t *p_adec )
421 aout_buffer_t *p_aout_buffer;
422 int i_samples; // per channels
427 /* **** get samples count **** */
428 input_ExtractPES( p_adec->p_fifo, &p_pes );
431 p_adec->p_fifo->b_error = 1;
434 i_size = p_pes->i_pes_size;
436 if( p_adec->p_wf->nBlockAlign > 0 )
438 i_size -= i_size % p_adec->p_wf->nBlockAlign;
440 if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
442 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
446 i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
447 p_adec->p_wf->nChannels;
449 p_adec->pts = p_pes->i_pts;
451 /* **** Now we can output these samples **** */
453 if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
455 aout_DateSet( &p_adec->date, p_adec->pts );
457 else if( !aout_DateGet( &p_adec->date ) )
463 p = p_data = malloc( i_size );
464 GetPESData( p_data, i_size, p_pes );
466 while( i_samples > 0 )
470 i_copy = __MIN( i_samples, 1024 );
471 p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
472 p_adec->p_aout_input,
476 msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
477 p_adec->p_fifo->b_error = 1;
483 p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
484 p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
487 if( p_adec->p_logtos16 )
489 int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
493 for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
495 *s++ = p_adec->p_logtos16[*p++];
500 memcpy( p_aout_buffer->p_buffer, p,
501 p_aout_buffer->i_nb_bytes );
503 p += p_aout_buffer->i_nb_bytes;
506 aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
512 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
515 /*****************************************************************************
516 * EndThread : faad decoder thread destruction
517 *****************************************************************************/
518 static void EndThread (adec_thread_t *p_adec)
520 if( p_adec->p_aout_input )
522 aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
525 msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );