X-Git-Url: https://git.sesse.net/?a=blobdiff_plain;f=modules%2Fcodec%2Ffaad.c;h=6fd6e3e346e81dbeef07e6bd5febe6116ad05ea2;hb=c72b18511552f25b386517406d71b4f7d5da3382;hp=cc75d8a2d3a83fb3a20a55a468517fb0ca024715;hpb=a90a19a6b0468ea9fedadc27cfc1118d70295263;p=vlc diff --git a/modules/codec/faad.c b/modules/codec/faad.c index cc75d8a2d3..6fd6e3e346 100644 --- a/modules/codec/faad.c +++ b/modules/codec/faad.c @@ -1,7 +1,7 @@ /***************************************************************************** * decoder.c: AAC decoder using libfaad2 ***************************************************************************** - * Copyright (C) 2001, 2003 VideoLAN + * Copyright (C) 2001, 2003 the VideoLAN team * $Id$ * * Authors: Laurent Aimar @@ -19,12 +19,13 @@ * * 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. + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA. *****************************************************************************/ #include -#include -#include +#include +#include +#include #include @@ -66,6 +67,10 @@ struct decoder_sys_t /* Channel positions of the current stream (for re-ordering) */ uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS]; + + vlc_bool_t b_sbr, b_ps; + + int i_input_rate; }; static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] = @@ -118,7 +123,7 @@ static int Open( vlc_object_t *p_this ) aout_DateSet( &p_sys->date, 0 ); p_dec->fmt_out.i_cat = AUDIO_ES; - if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) + if (vlc_CPU() & CPU_CAPABILITY_FPU) p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2'); else p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE; @@ -153,7 +158,7 @@ static int Open( vlc_object_t *p_this ) /* Set the faad config */ cfg = faacDecGetCurrentConfiguration( p_sys->hfaad ); - if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) + if (vlc_CPU() & CPU_CAPABILITY_FPU) cfg->outputFormat = FAAD_FMT_FLOAT; else cfg->outputFormat = FAAD_FMT_16BIT; @@ -163,9 +168,12 @@ static int Open( vlc_object_t *p_this ) p_sys->i_buffer = p_sys->i_buffer_size = 0; p_sys->p_buffer = 0; + p_sys->i_input_rate = INPUT_RATE_DEFAULT; + /* Faad2 can't deal with truncated data (eg. from MPEG TS) */ p_dec->b_need_packetized = VLC_TRUE; + p_sys->b_sbr = p_sys->b_ps = VLC_FALSE; return VLC_SUCCESS; } @@ -181,12 +189,15 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_block = *pp_block; - if( p_block->i_flags&BLOCK_FLAG_DISCONTINUITY ) + if( p_block->i_flags&(BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) ) { block_Release( p_block ); return NULL; } + if( p_block->i_rate > 0 ) + p_sys->i_input_rate = p_block->i_rate; + /* Append the block to the temporary buffer */ if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer ) { @@ -311,28 +322,51 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_dec->fmt_out.audio.i_rate = frame.samplerate; p_dec->fmt_out.audio.i_channels = frame.channels; + /* Adjust stream info when dealing with SBR/PS */ + if( (p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps) && + p_dec->p_parent->i_object_type == VLC_OBJECT_INPUT ) + { + input_thread_t *p_input = (input_thread_t *)p_dec->p_parent; + char *psz_cat; + const char *psz_ext = (frame.sbr && frame.ps) ? "SBR+PS" : + frame.sbr ? "SBR" : "PS"; + + msg_Dbg( p_dec, "AAC %s (channels: %u, samplerate: %lu)", + psz_ext, frame.channels, frame.samplerate ); + + asprintf( &psz_cat, _("Stream %d"), p_dec->fmt_in.i_id ); + input_Control( p_input, INPUT_ADD_INFO, psz_cat, + _("AAC extension"), "%s", psz_ext ); + input_Control( p_input, INPUT_ADD_INFO, psz_cat, + _("Channels"), "%d", frame.channels ); + input_Control( p_input, INPUT_ADD_INFO, psz_cat, + _("Sample rate"), _("%d Hz"), frame.samplerate ); + free( psz_cat ); + p_sys->b_sbr = frame.sbr; p_sys->b_ps = frame.ps; + } /* Convert frame.channel_position to our own channel values */ + p_dec->fmt_out.audio.i_physical_channels = 0; for( i = 0; i < frame.channels; i++ ) { /* Find the channel code */ for( j = 0; j < MAX_CHANNEL_POSITIONS; j++ ) { if( frame.channel_position[i] == pi_channels_in[j] ) - { - p_sys->pi_channel_positions[i] = pi_channels_out[j]; - p_dec->fmt_out.audio.i_physical_channels |= - pi_channels_out[j]; break; - } } - - if( j == MAX_CHANNEL_POSITIONS ) + if( j >= MAX_CHANNEL_POSITIONS ) { msg_Warn( p_dec, "unknown channel ordering" ); - block_Release( p_block ); - return NULL; + /* Invent something */ + j = i; } + /* */ + p_sys->pi_channel_positions[i] = pi_channels_out[j]; + if( p_dec->fmt_out.audio.i_physical_channels & pi_channels_out[j] ) + frame.channels--; /* We loose a duplicated channel */ + else + p_dec->fmt_out.audio.i_physical_channels |= pi_channels_out[j]; } p_dec->fmt_out.audio.i_original_channels = p_dec->fmt_out.audio.i_physical_channels; @@ -347,7 +381,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) p_out->start_date = aout_DateGet( &p_sys->date ); p_out->end_date = aout_DateIncrement( &p_sys->date, - frame.samples / frame.channels ); + (frame.samples / frame.channels) * p_sys->i_input_rate / INPUT_RATE_DEFAULT ); DoReordering( p_dec, (uint32_t *)p_out->p_buffer, samples, frame.samples / frame.channels, frame.channels, @@ -376,6 +410,7 @@ static void Close( vlc_object_t *p_this ) decoder_sys_t *p_sys = p_dec->p_sys; faacDecClose( p_sys->hfaad ); + if( p_sys->p_buffer ) free( p_sys->p_buffer ); free( p_sys ); } @@ -391,9 +426,9 @@ static void DoReordering( decoder_t *p_dec, int i, j, k; /* Find the channels mapping */ - for( i = 0, j = 0; i < MAX_CHANNEL_POSITIONS; i++ ) + for( k = 0, j = 0; k < i_nb_channels; k++ ) { - for( k = 0; k < i_nb_channels; k++ ) + for( i = 0; i < MAX_CHANNEL_POSITIONS; i++ ) { if( pi_channels_ordered[i] == pi_chan_positions[k] ) { @@ -404,7 +439,7 @@ static void DoReordering( decoder_t *p_dec, } /* Do the actual reordering */ - if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_FPU ) + if( vlc_CPU() & CPU_CAPABILITY_FPU ) for( i = 0; i < i_samples; i++ ) for( j = 0; j < i_nb_channels; j++ ) p_out[i * i_nb_channels + pi_chan_table[j]] =