--- /dev/null
+/*****************************************************************************
+ * decoder.c: AAC decoder using libfaad2
+ *****************************************************************************
+ * Copyright (C) 2001, 2003 VideoLAN
+ * $Id: faad.c,v 1.1 2003/11/03 22:30:15 fenrir Exp $
+ *
+ * Authors: Laurent Aimar <fenrir@via.ecp.fr>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
+ *****************************************************************************/
+
+#include <stdlib.h>
+
+#include <vlc/aout.h>
+#include <vlc/decoder.h>
+#include <vlc/input.h>
+
+#include <faad.h>
+#include "codecs.h"
+
+/*****************************************************************************
+ * Module descriptor
+ *****************************************************************************/
+static int Open( vlc_object_t * );
+
+vlc_module_begin();
+ set_description( _("AAC audio decoder (using libfaad2)") );
+ set_capability( "decoder", 60 );
+ set_callbacks( Open, NULL );
+vlc_module_end();
+
+
+/****************************************************************************
+ * Local prototypes
+ ****************************************************************************/
+static int InitDecoder ( decoder_t * );
+static int RunDecoder ( decoder_t *, block_t * );
+static int EndDecoder ( decoder_t * );
+
+struct decoder_sys_t
+{
+ /* faad handler */
+ faacDecHandle *hfaad;
+
+ /* audio output */
+ audio_sample_format_t output_format;
+ aout_instance_t * p_aout; /* opaque */
+ aout_input_t * p_aout_input; /* opaque */
+
+ /* samples */
+ audio_date_t date;
+
+ /* temporary buffer */
+ uint8_t *p_buffer;
+ int i_buffer;
+ int i_buffer_size;
+};
+
+/*****************************************************************************
+ * OpenDecoder: probe the decoder and return score
+ *****************************************************************************/
+static int Open( vlc_object_t *p_this )
+{
+ decoder_t *p_dec = (decoder_t*)p_this;
+
+ if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
+ {
+ return VLC_EGENERIC;
+ }
+
+ p_dec->pf_init = InitDecoder;
+ p_dec->pf_decode = RunDecoder;
+ p_dec->pf_end = EndDecoder;
+
+ p_dec->p_sys = malloc( sizeof( decoder_sys_t ) );
+
+ return VLC_SUCCESS;
+}
+
+static unsigned int pi_channels_maps[7] =
+{
+ 0,
+ AOUT_CHAN_CENTER,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+ AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
+ /* FIXME */
+ AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER
+};
+
+/*****************************************************************************
+ * InitDecoder:
+ *****************************************************************************/
+static int InitDecoder ( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+ WAVEFORMATEX wf, *p_wf;
+ faacDecConfiguration *cfg;
+
+ if( ( p_wf = (WAVEFORMATEX*)p_dec->p_fifo->p_waveformatex ) == NULL )
+ {
+ p_wf = &wf;
+ memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
+ }
+
+ /* Open a faad context */
+ if( ( p_sys->hfaad = faacDecOpen() ) == NULL )
+ {
+ msg_Err( p_dec, "Cannot initialize faad" );
+ return VLC_EGENERIC;
+ }
+
+ if( p_wf->cbSize > 0 )
+ {
+ /* We have a decoder config so init the handle */
+ unsigned long i_rate;
+ unsigned char i_channels;
+
+ if( faacDecInit2( p_sys->hfaad,
+ (uint8_t*)&p_wf[1], p_wf->cbSize,
+ &i_rate, &i_channels ) < 0 )
+ {
+ return VLC_EGENERIC;
+ }
+
+ p_sys->output_format.i_rate = i_rate;
+ p_sys->output_format.i_physical_channels =
+ p_sys->output_format.i_original_channels =
+ pi_channels_maps[i_channels];
+ }
+ else
+ {
+ /* Will be initalised from first frame */
+ p_sys->output_format.i_rate = 0;
+ p_sys->output_format.i_physical_channels =
+ p_sys->output_format.i_original_channels = 0;
+ }
+ p_sys->output_format.i_format = VLC_FOURCC('f','l','3','2');
+
+ p_sys->p_aout = NULL;
+ p_sys->p_aout_input = NULL;
+
+ /* set the faad config */
+ cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
+ cfg->outputFormat = FAAD_FMT_FLOAT;
+ faacDecSetConfiguration( p_sys->hfaad, cfg );
+
+ /* buffer */
+ p_sys->i_buffer = 0;
+ p_sys->i_buffer_size = 10000;
+ p_sys->p_buffer = malloc( p_sys->i_buffer_size );
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * InitDecoder:
+ *****************************************************************************/
+static int RunDecoder ( decoder_t *p_dec, block_t *p_block )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ int i_used = 0;
+ mtime_t i_pts = p_block->i_pts;
+
+ /* Append the block to the temporary buffer */
+ if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
+ {
+ p_sys->i_buffer_size += p_block->i_buffer;
+ p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
+ }
+ memcpy( &p_sys->p_buffer[p_sys->i_buffer], p_block->p_buffer, p_block->i_buffer );
+ p_sys->i_buffer += p_block->i_buffer;
+
+ if( p_sys->output_format.i_rate == 0 )
+ {
+ unsigned long i_rate;
+ unsigned char i_channels;
+
+ /* Init faad with the first frame */
+ if( faacDecInit( p_sys->hfaad,
+ p_sys->p_buffer, p_sys->i_buffer,
+ &i_rate, &i_channels ) < 0 )
+ {
+ return VLC_EGENERIC;
+ }
+ p_sys->output_format.i_rate = i_rate;
+ p_sys->output_format.i_physical_channels =
+ p_sys->output_format.i_original_channels =
+ pi_channels_maps[i_channels];
+ }
+
+ /* Decode all data */
+ while( i_used < p_sys->i_buffer )
+ {
+ void *samples;
+ faacDecFrameInfo frame;
+ aout_buffer_t *out;
+
+ samples = faacDecDecode( p_sys->hfaad, &frame,
+ &p_sys->p_buffer[i_used], p_sys->i_buffer - i_used );
+
+ if( frame.error > 0 )
+ {
+ msg_Warn( p_dec, "%s", faacDecGetErrorMessage( frame.error ) );
+ /* flush the buffer */
+ p_sys->i_buffer = 0;
+ return VLC_SUCCESS;
+ }
+ if( frame.channels <= 0 || frame.channels > 6 )
+ {
+ msg_Warn( p_dec, "invalid channels count" );
+ /* flush the buffer */
+ p_sys->i_buffer = 0;
+ return VLC_SUCCESS;
+ }
+ if( frame.samples <= 0 )
+ {
+ msg_Warn( p_dec, "decoded zero samples" );
+ /* flush the buffer */
+ p_sys->i_buffer = 0;
+ return VLC_SUCCESS;
+ }
+
+ /* we have decoded a valid frame */
+ /* msg_Dbg( p_dec, "consumed %d for %dHz %dc %lld", frame.bytesconsumed, frame.samplerate, frame.channels, i_pts ); */
+ i_used += frame.bytesconsumed;
+
+
+ /* create/recreate the output */
+ if( p_sys->p_aout_input &&
+ ( p_sys->output_format.i_original_channels != pi_channels_maps[frame.channels] ||
+ p_sys->output_format.i_rate != frame.samplerate ) )
+ {
+ aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+ p_sys->p_aout_input = NULL;
+ }
+
+ if( p_sys->p_aout_input == NULL )
+ {
+ p_sys->output_format.i_physical_channels =
+ p_sys->output_format.i_original_channels = pi_channels_maps[frame.channels];
+ p_sys->output_format.i_rate = frame.samplerate;
+
+ aout_DateInit( &p_sys->date, p_sys->output_format.i_rate );
+ aout_DateSet( &p_sys->date, 0 );
+
+ p_sys->p_aout_input = aout_DecNew( p_dec, &p_sys->p_aout, &p_sys->output_format );
+ }
+
+ if( p_sys->p_aout_input == NULL )
+ {
+ msg_Err( p_dec, "cannot create aout" );
+ return VLC_EGENERIC;
+ }
+
+ if( i_pts != 0 && i_pts != aout_DateGet( &p_sys->date ) )
+ {
+ aout_DateSet( &p_sys->date, i_pts );
+ }
+ else if( !aout_DateGet( &p_sys->date ) )
+ {
+ /* Wait for a dated packet */
+ msg_Dbg( p_dec, "no date" );
+ p_sys->i_buffer = 0;
+ return VLC_SUCCESS;
+ }
+ i_pts = 0; /* PTS is valid only once */
+
+ if( ( out = aout_DecNewBuffer( p_sys->p_aout, p_sys->p_aout_input,
+ frame.samples / frame.channels ) ) == NULL )
+ {
+ msg_Err( p_dec, "cannot get a new buffer" );
+ return VLC_EGENERIC;
+ }
+ out->start_date = aout_DateGet( &p_sys->date );
+ out->end_date = aout_DateIncrement( &p_sys->date,
+ frame.samples / frame.channels );
+ memcpy( out->p_buffer, samples, out->i_nb_bytes );
+
+ aout_DecPlay( p_sys->p_aout, p_sys->p_aout_input, out );
+ }
+
+ p_sys->i_buffer -= i_used;
+ if( p_sys->i_buffer > 0 )
+ {
+ memmove( &p_sys->p_buffer[0], &p_sys->p_buffer[i_used], p_sys->i_buffer );
+ }
+
+ return VLC_SUCCESS;
+}
+
+/*****************************************************************************
+ * InitDecoder:
+ *****************************************************************************/
+static int EndDecoder ( decoder_t *p_dec )
+{
+ decoder_sys_t *p_sys = p_dec->p_sys;
+
+ if( p_sys->p_aout_input )
+ {
+ aout_DecDelete( p_sys->p_aout, p_sys->p_aout_input );
+ }
+
+ faacDecClose( p_sys->hfaad );
+ free( p_sys );
+
+ return VLC_SUCCESS;
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+++ /dev/null
-/*****************************************************************************
- * decoder.c: AAC decoder using libfaad2
- *****************************************************************************
- * Copyright (C) 2001, 2002 VideoLAN
- * $Id: decoder.c,v 1.31 2003/09/09 12:36:24 hartman Exp $
- *
- * Authors: Laurent Aimar <fenrir@via.ecp.fr>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
-
-/*****************************************************************************
- * Preamble
- *****************************************************************************/
-#include <vlc/vlc.h>
-#include <vlc/aout.h>
-#include <vlc/decoder.h>
-#include <vlc/input.h>
-
-#include <stdlib.h> /* malloc(), free() */
-#include <string.h> /* strdup() */
-
-#include <faad.h>
-#include "codecs.h"
-#include "decoder.h"
-
-
-/*****************************************************************************
- * Local prototypes
- *****************************************************************************/
-static int OpenDecoder ( vlc_object_t * );
-
-static int RunDecoder ( decoder_fifo_t * );
-static int InitThread ( adec_thread_t * );
-static void DecodeThread ( adec_thread_t * );
-static void EndThread ( adec_thread_t * );
-
-/*****************************************************************************
- * Module descriptor
- *****************************************************************************/
-
-vlc_module_begin();
- set_description( _("AAC audio decoder (using libfaad2)") );
- set_capability( "decoder", 60 );
- set_callbacks( OpenDecoder, NULL );
-vlc_module_end();
-
-/*****************************************************************************
- * OpenDecoder: probe the decoder and return score
- *****************************************************************************
- * Tries to launch a decoder and return score so that the interface is able
- * to choose.
- *****************************************************************************/
-static int OpenDecoder( vlc_object_t *p_this )
-{
- decoder_t *p_dec = (decoder_t*)p_this;
-
- if( p_dec->p_fifo->i_fourcc != VLC_FOURCC('m','p','4','a') )
- {
- return VLC_EGENERIC;
- }
-
- p_dec->pf_run = RunDecoder;
- return VLC_SUCCESS;
-}
-
-/*****************************************************************************
- * RunDecoder: this function is called just after the thread is created
- *****************************************************************************/
-static int RunDecoder( decoder_fifo_t *p_fifo )
-{
- adec_thread_t *p_adec;
- int b_error;
-
- if( !( p_adec = malloc( sizeof( adec_thread_t ) ) ) )
- {
- msg_Err( p_fifo, "out of memory" );
- DecoderError( p_fifo );
- return( -1 );
- }
- memset( p_adec, 0, sizeof( adec_thread_t ) );
-
- p_adec->p_fifo = p_fifo;
-
- if( InitThread( p_adec ) != 0 )
- {
- DecoderError( p_fifo );
- return( -1 );
- }
-
- while( ( !p_adec->p_fifo->b_die )&&( !p_adec->p_fifo->b_error ) )
- {
- DecodeThread( p_adec );
- }
-
-
- if( ( b_error = p_adec->p_fifo->b_error ) )
- {
- DecoderError( p_adec->p_fifo );
- }
-
- EndThread( p_adec );
- if( b_error )
- {
- return( -1 );
- }
-
- return( 0 );
-}
-
-static unsigned int pi_channels_maps[7] =
-{
- 0,
- AOUT_CHAN_CENTER,
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
- AOUT_CHAN_CENTER | AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT,
- /* FIXME */
- AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT | AOUT_CHAN_REARCENTER,
-
-};
-
-#define FREE( p ) if( p != NULL ) free( p ); p = NULL
-
-static void GetPESData( uint8_t *p_buf, int i_max, pes_packet_t *p_pes )
-{
- int i_copy;
- int i_count;
-
- data_packet_t *p_data;
-
- i_count = 0;
- p_data = p_pes->p_first;
- while( p_data != NULL && i_count < i_max )
- {
-
- i_copy = __MIN( p_data->p_payload_end - p_data->p_payload_start,
- i_max - i_count );
-
- if( i_copy > 0 )
- {
- memcpy( p_buf,
- p_data->p_payload_start,
- i_copy );
- }
-
- p_data = p_data->p_next;
- i_count += i_copy;
- p_buf += i_copy;
- }
-
- if( i_count < i_max )
- {
- memset( p_buf, 0, i_max - i_count );
- }
-}
-
-/*****************************************************************************
- * InitThread: initialize data before entering main loop
- *****************************************************************************/
-static int InitThread( adec_thread_t * p_adec )
-{
- WAVEFORMATEX wf, *p_wf;
- int i_status;
- unsigned long i_rate;
- unsigned char i_nb_channels;
-
- faacDecConfiguration *p_faad_config;
-
- if( ( p_wf = (WAVEFORMATEX*)p_adec->p_fifo->p_waveformatex ) == NULL )
- {
- msg_Warn( p_adec->p_fifo,
- "cannot load stream informations" );
- p_wf = &wf;
- memset( p_wf, 0, sizeof( WAVEFORMATEX ) );
- }
-
- p_adec->p_buffer = NULL;
- p_adec->i_buffer = 0;
-
-
- if( !( p_adec->p_handle = faacDecOpen() ) )
- {
- msg_Err( p_adec->p_fifo,
- "cannot initialize faad" );
- return( -1 );
- }
-
- if( p_wf->cbSize <= 0 )
- {
- int i_frame_size;
- pes_packet_t *p_pes;
-
- faacDecConfigurationPtr cfg;
-
- cfg = faacDecGetCurrentConfiguration( p_adec->p_handle );
- if( p_wf->nSamplesPerSec > 0 )
- {
- cfg->defSampleRate = p_wf->nSamplesPerSec;
- }
- faacDecSetConfiguration( p_adec->p_handle, cfg );
- msg_Warn( p_adec->p_fifo,
- "DecoderSpecificInfo missing, trying with first frame" );
- // gather first frame
- do
- {
- input_ExtractPES( p_adec->p_fifo, &p_pes );
- if( !p_pes )
- {
- return( -1 );
- }
- i_frame_size = p_pes->i_pes_size;
-
- if( i_frame_size > 0 )
- {
- if( p_adec->i_buffer < i_frame_size + 16 )
- {
- FREE( p_adec->p_buffer );
- p_adec->p_buffer = malloc( i_frame_size + 16 );
- p_adec->i_buffer = i_frame_size + 16;
- }
-
- GetPESData( p_adec->p_buffer, p_adec->i_buffer, p_pes );
- }
- else
- {
- input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
- }
- } while( i_frame_size <= 0 );
-
-#ifdef HAVE_OLD_FAAD2
- i_status = faacDecInit( p_adec->p_handle,
- p_adec->p_buffer,
- &i_rate,
- &i_nb_channels );
-#else
- i_status = faacDecInit( p_adec->p_handle,
- p_adec->p_buffer,
- i_frame_size,
- &i_rate,
- &i_nb_channels );
-#endif
-
- }
- else
- {
- i_status = faacDecInit2( p_adec->p_handle,
- (uint8_t*)&p_wf[1],
- p_wf->cbSize,
- &i_rate,
- &i_nb_channels );
- }
-
- if( i_status < 0 )
- {
- msg_Err( p_adec->p_fifo,
- "failed to initialize faad" );
- //faacDecClose( p_adec->p_handle );
- return( -1 );
- }
- msg_Dbg( p_adec->p_fifo,
- "faad intitialized, samplerate: %ldHz channels: %d",
- i_rate,
- i_nb_channels );
-
-
- /* set default configuration */
- p_faad_config = faacDecGetCurrentConfiguration( p_adec->p_handle );
- p_faad_config->outputFormat = FAAD_FMT_FLOAT;
- faacDecSetConfiguration( p_adec->p_handle, p_faad_config );
-
-
- /* Initialize the thread properties */
- p_adec->output_format.i_format = VLC_FOURCC('f','l','3','2');
- p_adec->output_format.i_rate = i_rate;
- p_adec->output_format.i_physical_channels =
- p_adec->output_format.i_original_channels =
- pi_channels_maps[i_nb_channels];
- p_adec->p_aout = NULL;
- p_adec->p_aout_input = NULL;
-
- p_adec->pts = 0;
-
- return( 0 );
-}
-
-/*****************************************************************************
- * DecodeThread: decodes a frame
- *****************************************************************************
- * XXX it will work only for frame based streams like from mp4 file
- * but it's the only way to use libfaad2 without having segfault
- * after 1 or 2 frames
- *****************************************************************************/
-static void DecodeThread( adec_thread_t *p_adec )
-{
- aout_buffer_t *p_aout_buffer;
-
- void *p_faad_buffer;
- faacDecFrameInfo faad_frame;
- int i_frame_size;
- pes_packet_t *p_pes;
- int i_used;
-
- /* **** Get a new frames from streams **** */
- do
- {
- input_ExtractPES( p_adec->p_fifo, &p_pes );
- if( !p_pes )
- {
- p_adec->p_fifo->b_error = 1;
- return;
- }
- if( p_pes->i_pts != 0 )
- {
- p_adec->pts = p_pes->i_pts;
- }
- i_frame_size = p_pes->i_pes_size;
-
- if( i_frame_size > 0 )
- {
- if( p_adec->i_buffer < i_frame_size + 16 )
- {
- FREE( p_adec->p_buffer );
- p_adec->p_buffer = malloc( i_frame_size + 16 );
- p_adec->i_buffer = i_frame_size + 16;
- }
-
- GetPESData( p_adec->p_buffer, p_adec->i_buffer, p_pes );
- }
- input_DeletePES( p_adec->p_fifo->p_packets_mgt, p_pes );
- } while( i_frame_size <= 0 );
-
-
- i_used = 0;
- while( i_used < i_frame_size )
- {
- /* **** decode this frame **** */
-#ifdef HAVE_OLD_FAAD2
- p_faad_buffer = faacDecDecode( p_adec->p_handle,
- &faad_frame,
- &p_adec->p_buffer[i_used] );
-#else
- p_faad_buffer = faacDecDecode( p_adec->p_handle,
- &faad_frame,
- &p_adec->p_buffer[i_used],
- i_frame_size - i_used );
-#endif
-
- /* **** some sanity checks to see if we have samples to out **** */
- if( faad_frame.error > 0 )
- {
- msg_Warn( p_adec->p_fifo, "%s",
- faacDecGetErrorMessage(faad_frame.error) );
- return;
- }
- if( ( faad_frame.channels <= 0 )||
- ( faad_frame.channels > AAC_MAXCHANNELS) ||
- ( faad_frame.channels > 6 ) )
- {
- msg_Warn( p_adec->p_fifo,
- "invalid channels count(%d)", faad_frame.channels );
- return;
- }
- if( faad_frame.samples <= 0 )
- {
- msg_Warn( p_adec->p_fifo, "decoded zero sample !" );
- return;
- }
-
-#if 0
- msg_Err( p_adec->p_fifo,
- "decoded frame samples:%d, rate:%d, channels:%d, consumed:%d",
- faad_frame.samples, faad_frame.samplerate,
- faad_frame.channels,
- faad_frame.bytesconsumed );
-#endif
- i_used += faad_frame.bytesconsumed;
-
- /* **** Now we can output these samples **** */
-
- /* **** First check if we have a valid output **** */
- if( !p_adec->p_aout_input ||
- p_adec->output_format.i_original_channels
- != pi_channels_maps[faad_frame.channels]
-#ifndef HAVE_OLD_FAAD2
- || ( faad_frame.samplerate &&
- p_adec->output_format.i_rate != faad_frame.samplerate )
-#endif
- )
- {
- if( p_adec->p_aout_input )
- {
- /* **** Delete the old **** */
- aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
- }
-
- /* **** Create a new audio output **** */
- p_adec->output_format.i_physical_channels =
- p_adec->output_format.i_original_channels =
- pi_channels_maps[faad_frame.channels];
-#ifndef HAVE_OLD_FAAD2
- if( faad_frame.samplerate )
- p_adec->output_format.i_rate = faad_frame.samplerate;
-#endif
-
- aout_DateInit( &p_adec->date, p_adec->output_format.i_rate );
- p_adec->p_aout_input = aout_DecNew( p_adec->p_fifo,
- &p_adec->p_aout,
- &p_adec->output_format );
- }
-
- if( !p_adec->p_aout_input )
- {
- msg_Err( p_adec->p_fifo, "cannot create aout" );
- return;
- }
-
- if( p_adec->pts != 0 && p_adec->pts != aout_DateGet( &p_adec->date ) )
- {
- aout_DateSet( &p_adec->date, p_adec->pts );
- }
- else if( !aout_DateGet( &p_adec->date ) )
- {
- return;
- }
-
- p_aout_buffer = aout_DecNewBuffer( p_adec->p_aout,
- p_adec->p_aout_input,
- faad_frame.samples / faad_frame.channels );
- if( !p_aout_buffer )
- {
- msg_Err( p_adec->p_fifo, "cannot get aout buffer" );
- p_adec->p_fifo->b_error = 1;
- return;
- }
- p_aout_buffer->start_date = aout_DateGet( &p_adec->date );
- p_aout_buffer->end_date = aout_DateIncrement( &p_adec->date,
- faad_frame.samples /
- faad_frame.channels );
- memcpy( p_aout_buffer->p_buffer,
- p_faad_buffer,
- p_aout_buffer->i_nb_bytes );
-
- aout_DecPlay( p_adec->p_aout, p_adec->p_aout_input, p_aout_buffer );
- }
-}
-
-
-/*****************************************************************************
- * EndThread : faad decoder thread destruction
- *****************************************************************************/
-static void EndThread (adec_thread_t *p_adec)
-{
- if( p_adec->p_aout_input )
- {
- aout_DecDelete( p_adec->p_aout, p_adec->p_aout_input );
- }
-
- if( p_adec->p_handle )
- {
- faacDecClose( p_adec->p_handle );
- }
-
- FREE( p_adec->p_buffer );
-
- msg_Dbg( p_adec->p_fifo, "faad decoder closed" );
-
- free( p_adec );
-}