1 /*****************************************************************************
2 * araw.c: Pseudo audio decoder; for raw pcm data
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: araw.c,v 1.18 2003/10/25 00:49:13 sam 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 int16_t
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_t *p_dec = (decoder_t*)p_this;
85 switch( p_dec->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_dec->pf_run = RunDecoder;
101 static int pi_channels_maps[6] =
105 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
106 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER,
107 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT,
108 AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER
109 | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARLEFT
112 static int16_t ulawtos16[256] =
114 -32124, -31100, -30076, -29052, -28028, -27004, -25980, -24956,
115 -23932, -22908, -21884, -20860, -19836, -18812, -17788, -16764,
116 -15996, -15484, -14972, -14460, -13948, -13436, -12924, -12412,
117 -11900, -11388, -10876, -10364, -9852, -9340, -8828, -8316,
118 -7932, -7676, -7420, -7164, -6908, -6652, -6396, -6140,
119 -5884, -5628, -5372, -5116, -4860, -4604, -4348, -4092,
120 -3900, -3772, -3644, -3516, -3388, -3260, -3132, -3004,
121 -2876, -2748, -2620, -2492, -2364, -2236, -2108, -1980,
122 -1884, -1820, -1756, -1692, -1628, -1564, -1500, -1436,
123 -1372, -1308, -1244, -1180, -1116, -1052, -988, -924,
124 -876, -844, -812, -780, -748, -716, -684, -652,
125 -620, -588, -556, -524, -492, -460, -428, -396,
126 -372, -356, -340, -324, -308, -292, -276, -260,
127 -244, -228, -212, -196, -180, -164, -148, -132,
128 -120, -112, -104, -96, -88, -80, -72, -64,
129 -56, -48, -40, -32, -24, -16, -8, 0,
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
148 static int16_t alawtos16[256] =
150 -5504, -5248, -6016, -5760, -4480, -4224, -4992, -4736,
151 -7552, -7296, -8064, -7808, -6528, -6272, -7040, -6784,
152 -2752, -2624, -3008, -2880, -2240, -2112, -2496, -2368,
153 -3776, -3648, -4032, -3904, -3264, -3136, -3520, -3392,
154 -22016, -20992, -24064, -23040, -17920, -16896, -19968, -18944,
155 -30208, -29184, -32256, -31232, -26112, -25088, -28160, -27136,
156 -11008, -10496, -12032, -11520, -8960, -8448, -9984, -9472,
157 -15104, -14592, -16128, -15616, -13056, -12544, -14080, -13568,
158 -344, -328, -376, -360, -280, -264, -312, -296,
159 -472, -456, -504, -488, -408, -392, -440, -424,
160 -88, -72, -120, -104, -24, -8, -56, -40,
161 -216, -200, -248, -232, -152, -136, -184, -168,
162 -1376, -1312, -1504, -1440, -1120, -1056, -1248, -1184,
163 -1888, -1824, -2016, -1952, -1632, -1568, -1760, -1696,
164 -688, -656, -752, -720, -560, -528, -624, -592,
165 -944, -912, -1008, -976, -816, -784, -880, -848,
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
184 /*****************************************************************************
185 * RunDecoder: this function is called just after the thread is created
186 *****************************************************************************/
187 static int RunDecoder( decoder_fifo_t *p_fifo )
189 adec_thread_t *p_adec;
192 if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
194 msg_Err( p_fifo, "out of memory" );
195 DecoderError( p_fifo );
198 memset( p_adec, 0, sizeof( adec_thread_t ) );
200 p_adec->p_fifo = p_fifo;
202 if( InitThread( p_adec ) != 0 )
204 DecoderError( p_fifo );
208 while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
210 DecodeThread( p_adec );
214 if( ( b_error = p_adec->p_fifo->b_error ) )
216 DecoderError( p_adec->p_fifo );
229 #define FREE( p ) if( p ) free( p ); p = NULL
231 /*****************************************************************************
232 * InitThread: initialize data before entering main loop
233 *****************************************************************************/
234 static int InitThread( adec_thread_t * p_adec )
236 if( ( p_adec->p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex )
239 msg_Err( p_adec->p_fifo, "unknown raw format" );
243 /* fixing some values */
244 if( ( p_adec->p_wf->wFormatTag == WAVE_FORMAT_PCM ||
245 p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )&&
246 !p_adec->p_wf->nBlockAlign )
248 p_adec->p_wf->nBlockAlign =
249 p_adec->p_wf->nChannels *
250 ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 );
253 msg_Dbg( p_adec->p_fifo,
254 "raw format: samplerate:%dHz channels:%d bits/sample:%d "
256 p_adec->p_wf->nSamplesPerSec,
257 p_adec->p_wf->nChannels,
258 p_adec->p_wf->wBitsPerSample,
259 p_adec->p_wf->nBlockAlign );
261 /* Initialize the thread properties */
262 p_adec->p_logtos16 = NULL;
263 if( p_adec->p_wf->wFormatTag == WAVE_FORMAT_IEEE_FLOAT )
265 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
268 p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
271 p_adec->output_format.i_format = VLC_FOURCC('f','l','6','4');
274 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
280 if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 't', 'w', 'o', 's' ) )
282 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
285 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
288 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','b');
291 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','b');
294 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','b');
297 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
301 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 's', 'o', 'w', 't' ) )
303 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
306 p_adec->output_format.i_format = VLC_FOURCC('s','8',' ',' ');
309 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
312 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
315 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
318 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
322 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'r', 'a', 'w' ) )
324 switch( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 )
327 p_adec->output_format.i_format = VLC_FOURCC('u','8',' ',' ');
330 p_adec->output_format.i_format = VLC_FOURCC('s','1','6','l');
333 p_adec->output_format.i_format = VLC_FOURCC('s','2','4','l');
336 p_adec->output_format.i_format = VLC_FOURCC('s','3','2','l');
339 msg_Err( p_adec->p_fifo, "bad parameters(bits/sample)" );
343 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'a', 'l', 'a', 'w' ) )
345 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
346 p_adec->p_logtos16 = alawtos16;
348 else if( p_adec->p_fifo->i_fourcc == VLC_FOURCC( 'u', 'l', 'a', 'w' ) )
350 p_adec->output_format.i_format = AOUT_FMT_S16_NE;
351 p_adec->p_logtos16 = ulawtos16;
354 p_adec->output_format.i_rate = p_adec->p_wf->nSamplesPerSec;
356 if( p_adec->p_wf->nChannels <= 0 || p_adec->p_wf->nChannels > 5 )
358 msg_Err( p_adec->p_fifo, "bad channels count(1-5)" );
362 p_adec->output_format.i_physical_channels =
363 p_adec->output_format.i_original_channels =
364 pi_channels_maps[p_adec->p_wf->nChannels];
365 p_adec->p_aout = NULL;
366 p_adec->p_aout_input = NULL;
368 /* **** Create a new audio output **** */
369 aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
370 p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
372 &p_adec->output_format );
373 if( !p_adec->p_aout_input )
375 msg_Err( p_adec->p_fifo, "cannot create aout" );
382 static void GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
387 data_packet_t *p_data;
390 p_data = p_pes->p_first;
391 while( p_data != NULL && i_count < i_max )
394 i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
400 p_data->p_payload_start,
404 p_data = p_data->p_next;
409 if( i_count < i_max )
411 memset( p_buf, 0, i_max - i_count );
415 /*****************************************************************************
416 * DecodeThread: decodes a frame
417 *****************************************************************************/
418 static void DecodeThread( adec_thread_t *p_adec )
420 aout_buffer_t *p_aout_buffer;
421 int i_samples; // per channels
426 /* **** get samples count **** */
427 input_ExtractPES( p_adec->p_fifo, &p_pes );
430 p_adec->p_fifo->b_error = 1;
433 i_size = p_pes->i_pes_size;
435 if( p_adec->p_wf->nBlockAlign > 0 )
437 i_size -= i_size % p_adec->p_wf->nBlockAlign;
439 if( i_size <= 0 || i_size < p_adec->p_wf->nBlockAlign )
441 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
445 i_samples = i_size / ( ( p_adec->p_wf->wBitsPerSample + 7 ) / 8 ) /
446 p_adec->p_wf->nChannels;
448 p_adec->pts = p_pes->i_pts;
450 /* **** Now we can output these samples **** */
452 if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
454 aout_DateSet( &p_adec->date, p_adec->pts );
456 else if( !aout_DateGet( &p_adec->date ) )
462 p = p_data = malloc( i_size );
463 GetPESData( p_data, i_size, p_pes );
465 while( i_samples > 0 )
469 i_copy = __MIN( i_samples, 1024 );
470 p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
471 p_adec->p_aout_input,
475 msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
476 p_adec->p_fifo->b_error = 1;
482 p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
483 p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
486 if( p_adec->p_logtos16 )
488 int16_t *s = (int16_t*)p_aout_buffer->p_buffer;
492 for( i = 0; i < p_aout_buffer->i_nb_bytes; i++ )
494 *s++ = p_adec->p_logtos16[*p++];
499 memcpy( p_aout_buffer->p_buffer, p,
500 p_aout_buffer->i_nb_bytes );
502 p += p_aout_buffer->i_nb_bytes;
505 aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
511 input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
514 /*****************************************************************************
515 * EndThread : faad decoder thread destruction
516 *****************************************************************************/
517 static void EndThread (adec_thread_t *p_adec)
519 if( p_adec->p_aout_input )
521 aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
524 msg_Dbg( p_adec->p_fifo, "raw audio decoder closed" );