Commit 62442c20 authored by Laurent Aimar's avatar Laurent Aimar

* all: ported the faad decoder to the new API (btw, aac HE untested).

 I have not kept the compatibility with older faad version (but check is
 still be  done in configure.ac). (I  didn't like it as  old version are
 really buggy).
parent 2afa5cea
dnl Autoconf settings for vlc
dnl $Id: configure.ac,v 1.101 2003/11/01 21:50:00 fenrir Exp $
dnl $Id: configure.ac,v 1.102 2003/11/03 22:30:14 fenrir Exp $
AC_INIT(vlc,0.6.3-cvs)
......@@ -3419,7 +3419,6 @@ AC_OUTPUT([
modules/audio_mixer/Makefile
modules/audio_output/Makefile
modules/codec/Makefile
modules/codec/faad/Makefile
modules/codec/ffmpeg/Makefile
modules/codec/ffmpeg/postprocessing/Makefile
modules/codec/spudec/Makefile
......
......@@ -17,3 +17,4 @@ SOURCES_libmpeg2 = libmpeg2.c
SOURCES_rawvideo = rawvideo.c
SOURCES_quicktime = quicktime.c
SOURCES_subsdec = subsdec.c
SOURCES_faad = faad.c
/*****************************************************************************
* 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;
}
.deps
.dirstamp
*.lo
*.la
*.dll
*.dylib
*.sl
*.so
Makefile.am
Makefile.in
Makefile
SOURCES_faad = \
decoder.c \
decoder.h \
$(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 );
}
/*****************************************************************************
* decoder.h: faad decoder modules
*
*****************************************************************************
* Copyright (C) 2001 VideoLAN
* $Id: decoder.h,v 1.6 2003/01/25 18:09:30 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.
*****************************************************************************/
#define AAC_MAXCHANNELS 64
typedef struct adec_thread_s
{
/*
* faad decoder session
*/
/* faad stuff */
faacDecHandle *p_handle;
/* The bit stream structure handles the PES stream at the bit level */
bit_stream_t bit_stream;
/*
* Input properties
*/
decoder_fifo_t *p_fifo;
uint8_t *p_buffer;
int i_buffer;
/*
* Output properties
*/
aout_instance_t * p_aout; /* opaque */
aout_input_t * p_aout_input; /* opaque */
audio_sample_format_t output_format;
audio_date_t date;
mtime_t pts;
} adec_thread_t;
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment