Commit 53ce9f15 authored by Jean-Paul Saman's avatar Jean-Paul Saman

Backport modules/codec/faad.c changes from trunk.

parent 3f198151
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
* decoder.c: AAC decoder using libfaad2 * decoder.c: AAC decoder using libfaad2
***************************************************************************** *****************************************************************************
* Copyright (C) 2001, 2003 the VideoLAN team * Copyright (C) 2001, 2003 the VideoLAN team
* $Id$ * $Id: 6211152101577786a1f92852dfe51b98bed24fd2 $
* *
* Authors: Laurent Aimar <fenrir@via.ecp.fr> * Authors: Laurent Aimar <fenrir@via.ecp.fr>
* Gildas Bazin <gbazin@videolan.org> * Gildas Bazin <gbazin@videolan.org>
...@@ -47,8 +47,7 @@ vlc_module_end(); ...@@ -47,8 +47,7 @@ vlc_module_end();
* Local prototypes * Local prototypes
****************************************************************************/ ****************************************************************************/
static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** ); static aout_buffer_t *DecodeBlock( decoder_t *, block_t ** );
static void DoReordering( decoder_t *, uint32_t *, uint32_t *, int, int, static void DoReordering( uint32_t *, uint32_t *, int, int, uint32_t * );
uint32_t * );
#define MAX_CHANNEL_POSITIONS 9 #define MAX_CHANNEL_POSITIONS 9
...@@ -63,12 +62,14 @@ struct decoder_sys_t ...@@ -63,12 +62,14 @@ struct decoder_sys_t
/* temporary buffer */ /* temporary buffer */
uint8_t *p_buffer; uint8_t *p_buffer;
int i_buffer; int i_buffer;
int i_buffer_size; size_t i_buffer_size;
/* Channel positions of the current stream (for re-ordering) */ /* Channel positions of the current stream (for re-ordering) */
uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS]; uint32_t pi_channel_positions[MAX_CHANNEL_POSITIONS];
vlc_bool_t b_sbr, b_ps; vlc_bool_t b_sbr, b_ps;
int i_input_rate;
}; };
static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] = static const uint32_t pi_channels_in[MAX_CHANNEL_POSITIONS] =
...@@ -87,6 +88,22 @@ static const uint32_t pi_channels_ordered[MAX_CHANNEL_POSITIONS] = ...@@ -87,6 +88,22 @@ static const uint32_t pi_channels_ordered[MAX_CHANNEL_POSITIONS] =
AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT, AOUT_CHAN_REARLEFT, AOUT_CHAN_REARRIGHT,
AOUT_CHAN_CENTER, AOUT_CHAN_REARCENTER, AOUT_CHAN_LFE AOUT_CHAN_CENTER, AOUT_CHAN_REARCENTER, AOUT_CHAN_LFE
}; };
static const uint32_t pi_channels_guessed[MAX_CHANNEL_POSITIONS] =
{ 0, AOUT_CHAN_CENTER, AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_LFE,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT | AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_REARLEFT
| AOUT_CHAN_REARRIGHT | AOUT_CHAN_CENTER | AOUT_CHAN_LFE,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_MIDDLELEFT
| AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_CENTER,
AOUT_CHAN_LEFT | AOUT_CHAN_RIGHT | AOUT_CHAN_MIDDLELEFT
| AOUT_CHAN_MIDDLERIGHT | AOUT_CHAN_REARLEFT | AOUT_CHAN_REARRIGHT
| AOUT_CHAN_CENTER | AOUT_CHAN_LFE
};
/***************************************************************************** /*****************************************************************************
* OpenDecoder: probe the decoder and return score * OpenDecoder: probe the decoder and return score
...@@ -121,7 +138,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -121,7 +138,7 @@ static int Open( vlc_object_t *p_this )
aout_DateSet( &p_sys->date, 0 ); aout_DateSet( &p_sys->date, 0 );
p_dec->fmt_out.i_cat = AUDIO_ES; p_dec->fmt_out.i_cat = AUDIO_ES;
if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) if (CPUCapabilities() & CPU_CAPABILITY_FPU)
p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2'); p_dec->fmt_out.i_codec = VLC_FOURCC('f','l','3','2');
else else
p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE; p_dec->fmt_out.i_codec = AOUT_FMT_S16_NE;
...@@ -145,6 +162,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -145,6 +162,9 @@ static int Open( vlc_object_t *p_this )
p_dec->fmt_out.audio.i_rate = i_rate; p_dec->fmt_out.audio.i_rate = i_rate;
p_dec->fmt_out.audio.i_channels = i_channels; p_dec->fmt_out.audio.i_channels = i_channels;
p_dec->fmt_out.audio.i_physical_channels
= p_dec->fmt_out.audio.i_original_channels
= pi_channels_guessed[i_channels];
aout_DateInit( &p_sys->date, i_rate ); aout_DateInit( &p_sys->date, i_rate );
} }
else else
...@@ -156,7 +176,7 @@ static int Open( vlc_object_t *p_this ) ...@@ -156,7 +176,7 @@ static int Open( vlc_object_t *p_this )
/* Set the faad config */ /* Set the faad config */
cfg = faacDecGetCurrentConfiguration( p_sys->hfaad ); cfg = faacDecGetCurrentConfiguration( p_sys->hfaad );
if (p_this->p_libvlc->i_cpu & CPU_CAPABILITY_FPU) if (CPUCapabilities() & CPU_CAPABILITY_FPU)
cfg->outputFormat = FAAD_FMT_FLOAT; cfg->outputFormat = FAAD_FMT_FLOAT;
else else
cfg->outputFormat = FAAD_FMT_16BIT; cfg->outputFormat = FAAD_FMT_16BIT;
...@@ -164,7 +184,9 @@ static int Open( vlc_object_t *p_this ) ...@@ -164,7 +184,9 @@ static int Open( vlc_object_t *p_this )
/* buffer */ /* buffer */
p_sys->i_buffer = p_sys->i_buffer_size = 0; p_sys->i_buffer = p_sys->i_buffer_size = 0;
p_sys->p_buffer = 0; p_sys->p_buffer = NULL;
p_sys->i_input_rate = INPUT_RATE_DEFAULT;
/* Faad2 can't deal with truncated data (eg. from MPEG TS) */ /* Faad2 can't deal with truncated data (eg. from MPEG TS) */
p_dec->b_need_packetized = VLC_TRUE; p_dec->b_need_packetized = VLC_TRUE;
...@@ -191,6 +213,28 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -191,6 +213,28 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
return NULL; return NULL;
} }
if( p_block->i_rate > 0 )
p_sys->i_input_rate = p_block->i_rate;
/* Remove ADTS header if we have decoder specific config */
if( p_dec->fmt_in.i_extra && p_block->i_buffer > 7 )
{
if( p_block->p_buffer[0] == 0xff &&
( p_block->p_buffer[1] & 0xf0 ) == 0xf0 ) /* syncword */
{ /* ADTS header present */
size_t i_header_size; /* 7 bytes (+ 2 bytes for crc) */
i_header_size = 7 + ( ( p_block->p_buffer[1] & 0x01 ) ? 0 : 2 );
/* FIXME: multiple blocks per frame */
if( (size_t)p_block->i_buffer > i_header_size )
{
memcpy( p_block->p_buffer,
p_block->p_buffer + i_header_size,
p_block->i_buffer - i_header_size );
p_block->i_buffer -= i_header_size;
}
}
}
/* Append the block to the temporary buffer */ /* Append the block to the temporary buffer */
if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer ) if( p_sys->i_buffer_size < p_sys->i_buffer + p_block->i_buffer )
{ {
...@@ -198,7 +242,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -198,7 +242,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size ); p_sys->p_buffer = realloc( p_sys->p_buffer, p_sys->i_buffer_size );
} }
if( p_block->i_buffer ) if( p_block->i_buffer > 0 )
{ {
memcpy( &p_sys->p_buffer[p_sys->i_buffer], memcpy( &p_sys->p_buffer[p_sys->i_buffer],
p_block->p_buffer, p_block->i_buffer ); p_block->p_buffer, p_block->i_buffer );
...@@ -254,7 +298,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -254,7 +298,7 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
} }
/* Decode all data */ /* Decode all data */
if( p_sys->i_buffer ) if( p_sys->i_buffer > 0 )
{ {
void *samples; void *samples;
faacDecFrameInfo frame; faacDecFrameInfo frame;
...@@ -319,22 +363,25 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -319,22 +363,25 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
if( (p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps) && if( (p_sys->b_sbr != frame.sbr || p_sys->b_ps != frame.ps) &&
p_dec->p_parent->i_object_type == VLC_OBJECT_INPUT ) p_dec->p_parent->i_object_type == VLC_OBJECT_INPUT )
{ {
input_thread_t *p_input = (input_thread_t *)p_dec->p_parent; input_thread_t *p_input = (input_thread_t *)p_dec->p_parent;
char *psz_cat, *psz_ext = (frame.sbr && frame.ps) ? "SBR+PS" : char *psz_cat;
frame.sbr ? "SBR" : "PS"; 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 ); 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, if( asprintf( &psz_cat, _("Stream %d"), p_dec->fmt_in.i_id ) != -1 )
_("AAC extension"), "%s", psz_ext ); {
input_Control( p_input, INPUT_ADD_INFO, psz_cat, input_Control( p_input, INPUT_ADD_INFO, psz_cat,
_("Channels"), "%d", frame.channels ); _("AAC extension"), "%s", psz_ext );
input_Control( p_input, INPUT_ADD_INFO, psz_cat, input_Control( p_input, INPUT_ADD_INFO, psz_cat,
_("Sample rate"), _("%d Hz"), frame.samplerate ); _("Channels"), "%d", frame.channels );
free( psz_cat ); input_Control( p_input, INPUT_ADD_INFO, psz_cat,
p_sys->b_sbr = frame.sbr; p_sys->b_ps = frame.ps; _("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 */ /* Convert frame.channel_position to our own channel values */
...@@ -373,9 +420,9 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block ) ...@@ -373,9 +420,9 @@ static aout_buffer_t *DecodeBlock( decoder_t *p_dec, block_t **pp_block )
p_out->start_date = aout_DateGet( &p_sys->date ); p_out->start_date = aout_DateGet( &p_sys->date );
p_out->end_date = aout_DateIncrement( &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, DoReordering( (uint32_t *)p_out->p_buffer, samples,
frame.samples / frame.channels, frame.channels, frame.samples / frame.channels, frame.channels,
p_sys->pi_channel_positions ); p_sys->pi_channel_positions );
...@@ -402,7 +449,7 @@ static void Close( vlc_object_t *p_this ) ...@@ -402,7 +449,7 @@ static void Close( vlc_object_t *p_this )
decoder_sys_t *p_sys = p_dec->p_sys; decoder_sys_t *p_sys = p_dec->p_sys;
faacDecClose( p_sys->hfaad ); faacDecClose( p_sys->hfaad );
if( p_sys->p_buffer ) free( p_sys->p_buffer ); free( p_sys->p_buffer );
free( p_sys ); free( p_sys );
} }
...@@ -410,17 +457,16 @@ static void Close( vlc_object_t *p_this ) ...@@ -410,17 +457,16 @@ static void Close( vlc_object_t *p_this )
* DoReordering: do some channel re-ordering (the ac3 channel order is * DoReordering: do some channel re-ordering (the ac3 channel order is
* different from the aac one). * different from the aac one).
*****************************************************************************/ *****************************************************************************/
static void DoReordering( decoder_t *p_dec, static void DoReordering( uint32_t *p_out, uint32_t *p_in, int i_samples,
uint32_t *p_out, uint32_t *p_in, int i_samples,
int i_nb_channels, uint32_t *pi_chan_positions ) int i_nb_channels, uint32_t *pi_chan_positions )
{ {
int pi_chan_table[MAX_CHANNEL_POSITIONS]; int pi_chan_table[MAX_CHANNEL_POSITIONS];
int i, j, k; int i, j, k;
/* Find the channels mapping */ /* Find the channels mapping */
for( k = 0, j = 0; k < i_nb_channels; k++ ) for( i = 0, j = 0; i < MAX_CHANNEL_POSITIONS; i++ )
{ {
for( i = 0; i < MAX_CHANNEL_POSITIONS; i++ ) for( k = 0; k < i_nb_channels; k++ )
{ {
if( pi_channels_ordered[i] == pi_chan_positions[k] ) if( pi_channels_ordered[i] == pi_chan_positions[k] )
{ {
...@@ -431,7 +477,7 @@ static void DoReordering( decoder_t *p_dec, ...@@ -431,7 +477,7 @@ static void DoReordering( decoder_t *p_dec,
} }
/* Do the actual reordering */ /* Do the actual reordering */
if( p_dec->p_libvlc->i_cpu & CPU_CAPABILITY_FPU ) if( CPUCapabilities() & CPU_CAPABILITY_FPU )
for( i = 0; i < i_samples; i++ ) for( i = 0; i < i_samples; i++ )
for( j = 0; j < i_nb_channels; j++ ) for( j = 0; j < i_nb_channels; j++ )
p_out[i * i_nb_channels + pi_chan_table[j]] = p_out[i * i_nb_channels + pi_chan_table[j]] =
...@@ -442,3 +488,4 @@ static void DoReordering( decoder_t *p_dec, ...@@ -442,3 +488,4 @@ static void DoReordering( decoder_t *p_dec,
((uint16_t *)p_out)[i * i_nb_channels + pi_chan_table[j]] = ((uint16_t *)p_out)[i * i_nb_channels + pi_chan_table[j]] =
((uint16_t *)p_in)[i * i_nb_channels + j]; ((uint16_t *)p_in)[i * i_nb_channels + j];
} }
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