1 /*****************************************************************************
2 * decoder.c: AAC decoder using libfaad2
3 *****************************************************************************
4 * Copyright (C) 2001, 2002 VideoLAN
5 * $Id: decoder.c,v 1.4 2002/09/28 13:05:16 massiot 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() */
40 /*****************************************************************************
42 *****************************************************************************/
43 static int OpenDecoder ( vlc_object_t * );
45 static int RunDecoder ( decoder_fifo_t * );
46 static int InitThread ( adec_thread_t * );
47 static void DecodeThread ( adec_thread_t * );
48 static void EndThread ( adec_thread_t * );
50 /*****************************************************************************
52 *****************************************************************************/
55 set_description( _("AAC decoder module (libfaad2)") );
56 set_capability( "decoder", 60 );
57 set_callbacks( OpenDecoder, NULL );
60 /*****************************************************************************
61 * OpenDecoder: probe the decoder and return score
62 *****************************************************************************
63 * Tries to launch a decoder and return score so that the interface is able
65 *****************************************************************************/
66 static int OpenDecoder( vlc_object_t *p_this )
68 decoder_fifo_t *p_fifo = (decoder_fifo_t*) p_this;
70 if( p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
75 p_fifo->pf_run = RunDecoder;
79 /*****************************************************************************
80 * RunDecoder: this function is called just after the thread is created
81 *****************************************************************************/
82 static int RunDecoder( decoder_fifo_t *p_fifo )
84 adec_thread_t *p_adec;
87 if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
89 msg_Err( p_fifo, "out of memory" );
90 DecoderError( p_fifo );
93 memset( p_adec, 0, sizeof( adec_thread_t ) );
95 p_adec->p_fifo = p_fifo;
97 if( InitThread( p_adec ) != 0 )
99 DecoderError( p_fifo );
103 while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
105 DecodeThread( p_adec );
109 if( ( b_error = p_adec->p_fifo->b_error ) )
111 DecoderError( p_adec->p_fifo );
124 #define FREE( p ) if( p ) free( p ); p = NULL
125 #define GetWLE( p ) \
126 ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) )
128 #define GetDWLE( p ) \
129 ( *(u8*)(p) + ( *((u8*)(p)+1) << 8 ) + \
130 ( *((u8*)(p)+2) << 16 ) + ( *((u8*)(p)+3) << 24 ) )
132 static void faac_GetWaveFormatEx( waveformatex_t *p_wh,
136 p_wh->i_formattag = GetWLE( p_data );
137 p_wh->i_channels = GetWLE( p_data + 2 );
138 p_wh->i_samplespersec = GetDWLE( p_data + 4 );
139 p_wh->i_avgbytespersec= GetDWLE( p_data + 8 );
140 p_wh->i_blockalign = GetWLE( p_data + 12 );
141 p_wh->i_bitspersample = GetWLE( p_data + 14 );
142 p_wh->i_size = GetWLE( p_data + 16 );
146 p_wh->p_data = malloc( p_wh->i_size );
147 memcpy( p_wh->p_data, p_data + 18, p_wh->i_size );
151 /* get the first pes from fifo */
152 static pes_packet_t *__PES_GET( decoder_fifo_t *p_fifo )
156 vlc_mutex_lock( &p_fifo->data_lock );
158 /* if fifo is emty wait */
159 while( !p_fifo->p_first )
163 vlc_mutex_unlock( &p_fifo->data_lock );
166 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
168 p_pes = p_fifo->p_first;
170 vlc_mutex_unlock( &p_fifo->data_lock );
175 /* free the first pes and go to next */
176 static void __PES_NEXT( decoder_fifo_t *p_fifo )
178 pes_packet_t *p_next;
180 vlc_mutex_lock( &p_fifo->data_lock );
182 p_next = p_fifo->p_first->p_next;
183 p_fifo->p_first->p_next = NULL;
184 input_DeletePES( p_fifo->p_packets_mgt, p_fifo->p_first );
185 p_fifo->p_first = p_next;
188 if( !p_fifo->p_first )
190 /* No PES in the fifo */
191 /* pp_last no longer valid */
192 p_fifo->pp_last = &p_fifo->p_first;
193 while( !p_fifo->p_first )
195 vlc_cond_signal( &p_fifo->data_wait );
196 vlc_cond_wait( &p_fifo->data_wait, &p_fifo->data_lock );
199 vlc_mutex_unlock( &p_fifo->data_lock );
202 static inline void __GetFrame( adec_thread_t *p_adec )
205 data_packet_t *p_data;
208 p_pes = __PES_GET( p_adec->p_fifo );
211 p_adec->pts = p_pes->i_pts;
214 while( ( !p_pes->i_nb_data )||( !p_pes->i_pes_size ) )
216 __PES_NEXT( p_adec->p_fifo );
217 p_pes = __PES_GET( p_adec->p_fifo );
219 p_adec->i_framesize = p_pes->i_pes_size;
220 if( p_pes->i_nb_data == 1 )
222 p_adec->p_framedata = p_pes->p_first->p_payload_start;
225 /* get a buffer and gather all data packet */
226 if( p_adec->i_buffer_size < p_pes->i_pes_size )
228 p_adec->i_buffer_size = 3 * p_pes->i_pes_size / 2;
229 if( p_adec->p_buffer )
231 p_adec->p_buffer = realloc( p_adec->p_buffer,
232 p_adec->i_buffer_size );
236 p_adec->p_buffer = malloc( p_adec->i_buffer_size );
240 p_buffer = p_adec->p_framedata = p_adec->p_buffer;
241 p_data = p_pes->p_first;
244 p_adec->p_fifo->p_vlc->pf_memcpy( p_buffer, p_data->p_payload_start,
245 p_data->p_payload_end - p_data->p_payload_start );
246 p_buffer += p_data->p_payload_end - p_data->p_payload_start;
247 p_data = p_data->p_next;
251 static inline void __NextFrame( adec_thread_t *p_adec )
253 __PES_NEXT( p_adec->p_fifo );
257 /*****************************************************************************
258 * InitThread: initialize data before entering main loop
259 *****************************************************************************/
260 static int InitThread( adec_thread_t * p_adec )
263 unsigned long i_rate;
264 unsigned char i_channels;
266 faacDecConfiguration *p_faad_config;
268 if( !p_adec->p_fifo->p_demux_data )
270 msg_Warn( p_adec->p_fifo,
271 "cannot load stream informations" );
275 faac_GetWaveFormatEx( &p_adec->format,
276 (u8*)p_adec->p_fifo->p_demux_data );
279 if( !( p_adec->p_handle = faacDecOpen() ) )
281 msg_Err( p_adec->p_fifo,
282 "cannot initialize faad" );
283 FREE( p_adec->format.p_data );
287 if( !p_adec->format.p_data )
290 msg_Warn( p_adec->p_fifo,
291 "DecoderSpecificInfo missing, trying with first frame" );
292 __GetFrame( p_adec );
294 i_status = faacDecInit( p_adec->p_handle,
298 // __NextFrame( p_adec );
302 i_status = faacDecInit2( p_adec->p_handle,
303 p_adec->format.p_data,
304 p_adec->format.i_size,
311 msg_Err( p_adec->p_fifo,
312 "failed to initialize faad" );
313 faacDecClose( p_adec->p_handle );
316 msg_Dbg( p_adec->p_fifo,
317 "faad intitialized, samplerate:%dHz channels:%d",
322 /* set default configuration */
323 p_faad_config = faacDecGetCurrentConfiguration( p_adec->p_handle );
324 p_faad_config->outputFormat = FAAD_FMT_FLOAT;
325 faacDecSetConfiguration( p_adec->p_handle, p_faad_config );
328 /* Initialize the thread properties */
329 p_adec->output_format.i_format = AOUT_FMT_FLOAT32;
330 p_adec->output_format.i_rate = i_rate;
331 p_adec->output_format.i_channels = i_channels;
332 p_adec->p_aout = NULL;
333 p_adec->p_aout_input = NULL;
336 if( !p_adec->format.p_data )
338 /* Init the BitStream */
339 InitBitstream( &p_adec->bit_stream, p_adec->p_fifo,
341 p_adec->p_framedata = malloc( AAC_MAXCHANNELS * FAAD_MIN_STREAMSIZE );
342 p_adec->i_framesize = 0;
349 /*****************************************************************************
350 * DecodeThread: decodes a frame
351 *****************************************************************************
352 * XXX it will work only for frame based streams like from mp4 file
353 * but it's the only way to use libfaad2 without having segfault
354 * after 1 or 2 frames
355 *****************************************************************************/
356 static void DecodeThread( adec_thread_t *p_adec )
358 aout_buffer_t *p_aout_buffer;
361 faacDecFrameInfo faad_frame;
363 /* **** Get a new frames from streams **** */
364 __GetFrame( p_adec );
366 /* **** decode this frame **** */
367 p_faad_buffer = faacDecDecode( p_adec->p_handle,
369 p_adec->p_framedata );
370 /* **** switch to the next frame **** */
371 __NextFrame( p_adec );
375 * XXX don't work ! XXX
377 * first even without format.p_data stream can be frame based
378 * and it make libfaad segfault
381 if( p_adec->format.p_data )
383 __GetFrame( p_adec );
384 /* Now decode data */
385 p_faad_buffer = faacDecDecode( p_adec->p_handle,
387 p_adec->p_framedata );
388 __NextFrame( p_adec );
395 i_count = __MAX( 1, p_adec->output_format.i_channels ) * FAAD_MIN_STREAMSIZE -
398 GetChunk( &p_adec->bit_stream,
399 p_adec->p_framedata + p_adec->i_framesize,
401 p_adec->i_framesize += i_count;
402 p_faad_buffer = faacDecDecode( p_adec->p_handle,
404 p_adec->p_framedata );
405 /* update data buffer pos */
406 i_count = __MIN( p_adec->i_framesize,
407 __MAX( 1, faad_frame.bytesconsumed ) );
408 memcpy( p_adec->p_framedata,
409 p_adec->p_framedata + i_count,
410 p_adec->i_framesize - i_count );
411 p_adec->i_framesize -= i_count;
415 /* **** some sanity checks to see if we have samples to out **** */
416 if( faad_frame.error > 0 )
418 msg_Warn( p_adec->p_fifo, "%s",
419 faacDecGetErrorMessage(faad_frame.error) );
422 if( ( faad_frame.channels <= 0 )||
423 ( faad_frame.channels > AAC_MAXCHANNELS) )
425 msg_Warn( p_adec->p_fifo,
426 "invalid channels count(%d)", faad_frame.channels );
429 if( faad_frame.samples <= 0 )
431 msg_Warn( p_adec->p_fifo, "decoded zero sample !" );
436 msg_Dbg( p_adec->p_fifo,
437 "decoded frame samples:%d, channels:%d, consumed:%d",
440 faad_frame.bytesconsumed );
443 /* **** Now we can output these samples **** */
445 /* **** First check if we have a valid output **** */
446 if( ( !p_adec->p_aout_input )||
447 ( p_adec->output_format.i_channels != faad_frame.channels ) )
449 if( p_adec->p_aout_input )
451 /* **** Delete the old **** */
452 aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
455 /* **** Create a new audio output **** */
456 p_adec->output_format.i_channels = faad_frame.channels;
457 aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
458 p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
460 &p_adec->output_format );
463 if( !p_adec->p_aout_input )
465 msg_Err( p_adec->p_fifo, "cannot create aout" );
469 if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
471 aout_DateSet( &p_adec->date, p_adec->pts );
473 else if( !aout_DateGet( &p_adec->date ) )
478 p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
479 p_adec->p_aout_input,
480 faad_frame.samples / faad_frame.channels );
483 msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
484 p_adec->p_fifo->b_error = 1;
487 p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
488 p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
490 faad_frame.channels );
491 memcpy( p_aout_buffer->p_buffer,
493 p_aout_buffer->i_nb_bytes );
495 aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
499 /*****************************************************************************
500 * EndThread : faad decoder thread destruction
501 *****************************************************************************/
502 static void EndThread (adec_thread_t *p_adec)
504 if( p_adec->p_aout_input )
506 aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
509 if( p_adec->p_handle )
511 faacDecClose( p_adec->p_handle );
514 FREE( p_adec->format.p_data );
515 FREE( p_adec->p_buffer );
517 msg_Dbg( p_adec->p_fifo, "faad decoder closed" );