2008-08-05 22:32:01 +03:00
/*
* AAC decoder
* Copyright ( c ) 2005 - 2006 Oded Shimon ( ods15 ods15 dyndns org )
* Copyright ( c ) 2006 - 2007 Maxim Gavrilov ( maxim . gavrilov gmail com )
*
* This file is part of FFmpeg .
*
* FFmpeg is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2.1 of the License , or ( at your option ) any later version .
*
* FFmpeg 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
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with FFmpeg ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Street , Fifth Floor , Boston , MA 02110 - 1301 USA
*/
/**
2009-02-01 04:00:19 +02:00
* @ file libavcodec / aac . c
2008-08-05 22:32:01 +03:00
* AAC decoder
* @ author Oded Shimon ( ods15 ods15 dyndns org )
* @ author Maxim Gavrilov ( maxim . gavrilov gmail com )
*/
/*
* supported tools
*
* Support ? Name
* N ( code in SoC repo ) gain control
* Y block switching
* Y window shapes - standard
* N window shapes - Low Delay
* Y filterbank - standard
* N ( code in SoC repo ) filterbank - Scalable Sample Rate
* Y Temporal Noise Shaping
* N ( code in SoC repo ) Long Term Prediction
* Y intensity stereo
* Y channel coupling
2008-11-24 02:13:50 +02:00
* Y frequency domain prediction
2008-08-05 22:32:01 +03:00
* Y Perceptual Noise Substitution
* Y Mid / Side stereo
* N Scalable Inverse AAC Quantization
* N Frequency Selective Switch
* N upsampling filter
* Y quantization & coding - AAC
* N quantization & coding - TwinVQ
* N quantization & coding - BSAC
* N AAC Error Resilience tools
* N Error Resilience payload syntax
* N Error Protection tool
* N CELP
* N Silence Compression
* N HVXC
* N HVXC 4 kbits / s VR
* N Structured Audio tools
* N Structured Audio Sample Bank Format
* N MIDI
* N Harmonic and Individual Lines plus Noise
* N Text - To - Speech Interface
* N ( in progress ) Spectral Band Replication
* Y ( not in this code ) Layer - 1
* Y ( not in this code ) Layer - 2
* Y ( not in this code ) Layer - 3
* N SinuSoidal Coding ( Transient , Sinusoid , Noise )
* N ( planned ) Parametric Stereo
* N Direct Stream Transfer
*
* Note : - HE AAC v1 comprises LC AAC with Spectral Band Replication .
* - HE AAC v2 comprises LC AAC with Spectral Band Replication and
Parametric Stereo .
*/
# include "avcodec.h"
2008-12-08 23:21:38 +02:00
# include "internal.h"
2009-04-13 19:20:26 +03:00
# include "get_bits.h"
2008-08-05 22:32:01 +03:00
# include "dsputil.h"
2008-09-04 14:03:14 +03:00
# include "lpc.h"
2008-08-05 22:32:01 +03:00
# include "aac.h"
# include "aactab.h"
2008-08-09 13:46:27 +03:00
# include "aacdectab.h"
2008-08-05 22:32:01 +03:00
# include "mpeg4audio.h"
2009-01-08 00:09:21 +02:00
# include "aac_parser.h"
2008-08-05 22:32:01 +03:00
# include <assert.h>
# include <errno.h>
# include <math.h>
# include <string.h>
2010-01-15 04:58:24 +02:00
# if ARCH_ARM
# include "arm / aac.h"
# endif
2009-08-02 13:50:59 +03:00
union float754 {
float f ;
uint32_t i ;
} ;
2009-03-16 18:11:27 +02:00
2008-08-05 22:32:01 +03:00
static VLC vlc_scalefactors ;
static VLC vlc_spectral [ 11 ] ;
2010-01-13 18:46:28 +02:00
static uint32_t cbrt_tab [ 1 < < 13 ] ;
2008-08-05 22:32:01 +03:00
2009-08-02 13:50:59 +03:00
static ChannelElement * get_che ( AACContext * ac , int type , int elem_id )
{
2009-03-06 21:47:01 +02:00
if ( ac - > tag_che_map [ type ] [ elem_id ] ) {
return ac - > tag_che_map [ type ] [ elem_id ] ;
}
if ( ac - > tags_mapped > = tags_per_config [ ac - > m4ac . chan_config ] ) {
return NULL ;
}
switch ( ac - > m4ac . chan_config ) {
2009-08-02 13:50:59 +03:00
case 7 :
if ( ac - > tags_mapped = = 3 & & type = = TYPE_CPE ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ TYPE_CPE ] [ elem_id ] = ac - > che [ TYPE_CPE ] [ 2 ] ;
}
case 6 :
/* Some streams incorrectly code 5.1 audio as SCE[0] CPE[0] CPE[1] SCE[1]
instead of SCE [ 0 ] CPE [ 0 ] CPE [ 0 ] LFE [ 0 ] . If we seem to have
encountered such a stream , transfer the LFE [ 0 ] element to SCE [ 1 ] */
if ( ac - > tags_mapped = = tags_per_config [ ac - > m4ac . chan_config ] - 1 & & ( type = = TYPE_LFE | | type = = TYPE_SCE ) ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ type ] [ elem_id ] = ac - > che [ TYPE_LFE ] [ 0 ] ;
}
case 5 :
if ( ac - > tags_mapped = = 2 & & type = = TYPE_CPE ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ TYPE_CPE ] [ elem_id ] = ac - > che [ TYPE_CPE ] [ 1 ] ;
}
case 4 :
if ( ac - > tags_mapped = = 2 & & ac - > m4ac . chan_config = = 4 & & type = = TYPE_SCE ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ TYPE_SCE ] [ elem_id ] = ac - > che [ TYPE_SCE ] [ 1 ] ;
}
case 3 :
case 2 :
if ( ac - > tags_mapped = = ( ac - > m4ac . chan_config ! = 2 ) & & type = = TYPE_CPE ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ TYPE_CPE ] [ elem_id ] = ac - > che [ TYPE_CPE ] [ 0 ] ;
} else if ( ac - > m4ac . chan_config = = 2 ) {
2009-03-06 21:47:01 +02:00
return NULL ;
2009-08-02 13:50:59 +03:00
}
case 1 :
if ( ! ac - > tags_mapped & & type = = TYPE_SCE ) {
ac - > tags_mapped + + ;
return ac - > tag_che_map [ TYPE_SCE ] [ elem_id ] = ac - > che [ TYPE_SCE ] [ 0 ] ;
}
default :
return NULL ;
2009-03-06 21:47:01 +02:00
}
}
2009-09-28 18:37:18 +03:00
/**
* Check for the channel element in the current channel position configuration .
* If it exists , make sure the appropriate element is allocated and map the
* channel order to match the internal FFmpeg channel layout .
*
* @ param che_pos current channel position configuration
* @ param type channel element type
* @ param id channel element id
* @ param channels count of the number of channels in the configuration
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
static int che_configure ( AACContext * ac ,
enum ChannelPosition che_pos [ 4 ] [ MAX_ELEM_ID ] ,
int type , int id ,
int * channels )
{
if ( che_pos [ type ] [ id ] ) {
if ( ! ac - > che [ type ] [ id ] & & ! ( ac - > che [ type ] [ id ] = av_mallocz ( sizeof ( ChannelElement ) ) ) )
return AVERROR ( ENOMEM ) ;
if ( type ! = TYPE_CCE ) {
ac - > output_data [ ( * channels ) + + ] = ac - > che [ type ] [ id ] - > ch [ 0 ] . ret ;
if ( type = = TYPE_CPE ) {
ac - > output_data [ ( * channels ) + + ] = ac - > che [ type ] [ id ] - > ch [ 1 ] . ret ;
}
}
} else
av_freep ( & ac - > che [ type ] [ id ] ) ;
return 0 ;
}
2008-08-15 03:05:09 +03:00
/**
* Configure output channel order based on the current program configuration element .
*
* @ param che_pos current channel position configuration
* @ param new_che_pos New channel position configuration - we only do something if it differs from the current one .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int output_configure ( AACContext * ac ,
enum ChannelPosition che_pos [ 4 ] [ MAX_ELEM_ID ] ,
enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ,
2009-11-04 00:50:02 +02:00
int channel_config , enum OCStatus oc_type )
2009-08-02 13:50:59 +03:00
{
2008-08-15 03:05:09 +03:00
AVCodecContext * avctx = ac - > avccontext ;
2009-09-28 18:37:18 +03:00
int i , type , channels = 0 , ret ;
2008-08-15 03:05:09 +03:00
memcpy ( che_pos , new_che_pos , 4 * MAX_ELEM_ID * sizeof ( new_che_pos [ 0 ] [ 0 ] ) ) ;
2009-09-28 18:35:13 +03:00
if ( channel_config ) {
for ( i = 0 ; i < tags_per_config [ channel_config ] ; i + + ) {
2009-09-28 18:37:18 +03:00
if ( ( ret = che_configure ( ac , che_pos ,
aac_channel_layout_map [ channel_config - 1 ] [ i ] [ 0 ] ,
aac_channel_layout_map [ channel_config - 1 ] [ i ] [ 1 ] ,
& channels ) ) )
return ret ;
2009-09-28 18:35:13 +03:00
}
memset ( ac - > tag_che_map , 0 , 4 * MAX_ELEM_ID * sizeof ( ac - > che [ 0 ] [ 0 ] ) ) ;
ac - > tags_mapped = 0 ;
avctx - > channel_layout = aac_channel_layout [ channel_config - 1 ] ;
} else {
2009-09-28 18:35:51 +03:00
/* Allocate or free elements depending on if they are in the
* current program configuration .
*
* Set up default 1 : 1 output mapping .
*
* For a 5.1 stream the output order will be :
* [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]
*/
for ( i = 0 ; i < MAX_ELEM_ID ; i + + ) {
for ( type = 0 ; type < 4 ; type + + ) {
2009-09-28 18:37:18 +03:00
if ( ( ret = che_configure ( ac , che_pos , type , i , & channels ) ) )
return ret ;
2009-09-28 18:35:51 +03:00
}
2008-08-15 03:05:09 +03:00
}
2009-03-06 21:47:01 +02:00
memcpy ( ac - > tag_che_map , ac - > che , 4 * MAX_ELEM_ID * sizeof ( ac - > che [ 0 ] [ 0 ] ) ) ;
2009-08-02 13:50:59 +03:00
ac - > tags_mapped = 4 * MAX_ELEM_ID ;
2009-09-28 18:35:13 +03:00
avctx - > channel_layout = 0 ;
2009-03-06 21:47:01 +02:00
}
2008-08-15 03:05:09 +03:00
avctx - > channels = channels ;
2009-03-06 21:47:01 +02:00
2009-11-04 00:50:02 +02:00
ac - > output_configured = oc_type ;
2009-07-11 00:53:04 +03:00
2008-08-15 03:05:09 +03:00
return 0 ;
}
2008-08-11 14:16:06 +03:00
/**
* Decode an array of 4 bit element IDs , optionally interleaved with a stereo / mono switching bit .
*
* @ param cpe_map Stereo ( Channel Pair Element ) map , NULL if stereo bit is not present .
* @ param sce_map mono ( Single Channel Element ) map
* @ param type speaker type / position for these channels
*/
static void decode_channel_map ( enum ChannelPosition * cpe_map ,
2009-08-02 13:50:59 +03:00
enum ChannelPosition * sce_map ,
enum ChannelPosition type ,
GetBitContext * gb , int n )
{
while ( n - - ) {
2008-08-11 14:16:06 +03:00
enum ChannelPosition * map = cpe_map & & get_bits1 ( gb ) ? cpe_map : sce_map ; // stereo or mono map
map [ get_bits ( gb , 4 ) ] = type ;
}
}
/**
* Decode program configuration element ; reference : table 4.2 .
*
* @ param new_che_pos New channel position configuration - we only do something if it differs from the current one .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_pce ( AACContext * ac , enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ,
GetBitContext * gb )
{
2008-12-21 07:08:32 +02:00
int num_front , num_side , num_back , num_lfe , num_assoc_data , num_cc , sampling_index ;
2008-08-11 14:16:06 +03:00
skip_bits ( gb , 2 ) ; // object_type
2008-12-21 07:08:32 +02:00
sampling_index = get_bits ( gb , 4 ) ;
2009-05-27 00:34:56 +03:00
if ( ac - > m4ac . sampling_index ! = sampling_index )
av_log ( ac - > avccontext , AV_LOG_WARNING , " Sample rate index in program config element does not match the sample rate index configured by the container. \n " ) ;
2008-08-05 22:32:01 +03:00
num_front = get_bits ( gb , 4 ) ;
num_side = get_bits ( gb , 4 ) ;
num_back = get_bits ( gb , 4 ) ;
num_lfe = get_bits ( gb , 2 ) ;
num_assoc_data = get_bits ( gb , 3 ) ;
num_cc = get_bits ( gb , 4 ) ;
2008-08-09 13:46:27 +03:00
if ( get_bits1 ( gb ) )
skip_bits ( gb , 4 ) ; // mono_mixdown_tag
if ( get_bits1 ( gb ) )
skip_bits ( gb , 4 ) ; // stereo_mixdown_tag
2008-08-05 22:32:01 +03:00
2008-08-09 13:46:27 +03:00
if ( get_bits1 ( gb ) )
skip_bits ( gb , 3 ) ; // mixdown_coeff_index and pseudo_surround
2008-08-05 22:32:01 +03:00
2008-08-09 13:46:27 +03:00
decode_channel_map ( new_che_pos [ TYPE_CPE ] , new_che_pos [ TYPE_SCE ] , AAC_CHANNEL_FRONT , gb , num_front ) ;
decode_channel_map ( new_che_pos [ TYPE_CPE ] , new_che_pos [ TYPE_SCE ] , AAC_CHANNEL_SIDE , gb , num_side ) ;
decode_channel_map ( new_che_pos [ TYPE_CPE ] , new_che_pos [ TYPE_SCE ] , AAC_CHANNEL_BACK , gb , num_back ) ;
decode_channel_map ( NULL , new_che_pos [ TYPE_LFE ] , AAC_CHANNEL_LFE , gb , num_lfe ) ;
2008-08-05 22:32:01 +03:00
skip_bits_long ( gb , 4 * num_assoc_data ) ;
2008-08-09 13:46:27 +03:00
decode_channel_map ( new_che_pos [ TYPE_CCE ] , new_che_pos [ TYPE_CCE ] , AAC_CHANNEL_CC , gb , num_cc ) ;
2008-08-05 22:32:01 +03:00
align_get_bits ( gb ) ;
/* comment field, first byte is length */
skip_bits_long ( gb , 8 * get_bits ( gb , 8 ) ) ;
2008-08-09 13:46:27 +03:00
return 0 ;
}
2008-08-05 22:32:01 +03:00
2008-08-11 14:16:06 +03:00
/**
* Set up channel positions based on a default channel configuration
* as specified in table 1.17 .
*
* @ param new_che_pos New channel position configuration - we only do something if it differs from the current one .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int set_default_channel_config ( AACContext * ac ,
enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ,
int channel_config )
2008-08-11 14:16:06 +03:00
{
2009-08-02 13:50:59 +03:00
if ( channel_config < 1 | | channel_config > 7 ) {
2008-08-11 14:16:06 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " invalid default channel configuration (%d) \n " ,
channel_config ) ;
return - 1 ;
}
/* default channel configurations:
*
* 1 ch : front center ( mono )
* 2 ch : L + R ( stereo )
* 3 ch : front center + L + R
* 4 ch : front center + L + R + back center
* 5 ch : front center + L + R + back stereo
* 6 ch : front center + L + R + back stereo + LFE
* 7 ch : front center + L + R + outer front left + outer front right + back stereo + LFE
*/
2009-08-02 13:50:59 +03:00
if ( channel_config ! = 2 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_SCE ] [ 0 ] = AAC_CHANNEL_FRONT ; // front center (or mono)
2009-08-02 13:50:59 +03:00
if ( channel_config > 1 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_CPE ] [ 0 ] = AAC_CHANNEL_FRONT ; // L + R (or stereo)
2009-08-02 13:50:59 +03:00
if ( channel_config = = 4 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_SCE ] [ 1 ] = AAC_CHANNEL_BACK ; // back center
2009-08-02 13:50:59 +03:00
if ( channel_config > 4 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_CPE ] [ ( channel_config = = 7 ) + 1 ]
2009-08-02 13:50:59 +03:00
= AAC_CHANNEL_BACK ; // back stereo
if ( channel_config > 5 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_LFE ] [ 0 ] = AAC_CHANNEL_LFE ; // LFE
2009-08-02 13:50:59 +03:00
if ( channel_config = = 7 )
2008-08-11 14:16:06 +03:00
new_che_pos [ TYPE_CPE ] [ 1 ] = AAC_CHANNEL_FRONT ; // outer front left + outer front right
return 0 ;
}
2008-08-15 03:05:09 +03:00
/**
* Decode GA " General Audio " specific configuration ; reference : table 4.1 .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_ga_specific_config ( AACContext * ac , GetBitContext * gb ,
int channel_config )
{
2008-08-15 03:05:09 +03:00
enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ;
int extension_flag , ret ;
2009-08-02 13:50:59 +03:00
if ( get_bits1 ( gb ) ) { // frameLengthFlag
2009-06-29 22:07:04 +03:00
av_log_missing_feature ( ac - > avccontext , " 960/120 MDCT window is " , 1 ) ;
2008-08-11 14:16:06 +03:00
return - 1 ;
}
if ( get_bits1 ( gb ) ) // dependsOnCoreCoder
skip_bits ( gb , 14 ) ; // coreCoderDelay
extension_flag = get_bits1 ( gb ) ;
2009-08-02 13:50:59 +03:00
if ( ac - > m4ac . object_type = = AOT_AAC_SCALABLE | |
ac - > m4ac . object_type = = AOT_ER_AAC_SCALABLE )
2008-08-11 14:16:06 +03:00
skip_bits ( gb , 3 ) ; // layerNr
memset ( new_che_pos , 0 , 4 * MAX_ELEM_ID * sizeof ( new_che_pos [ 0 ] [ 0 ] ) ) ;
if ( channel_config = = 0 ) {
skip_bits ( gb , 4 ) ; // element_instance_tag
2009-08-02 13:50:59 +03:00
if ( ( ret = decode_pce ( ac , new_che_pos , gb ) ) )
2008-08-11 14:16:06 +03:00
return ret ;
} else {
2009-08-02 13:50:59 +03:00
if ( ( ret = set_default_channel_config ( ac , new_che_pos , channel_config ) ) )
2008-08-11 14:16:06 +03:00
return ret ;
}
2009-12-02 11:12:05 +02:00
if ( ( ret = output_configure ( ac , ac - > che_pos , new_che_pos , channel_config , OC_GLOBAL_HDR ) ) )
2008-08-11 14:16:06 +03:00
return ret ;
if ( extension_flag ) {
switch ( ac - > m4ac . object_type ) {
2009-08-02 13:50:59 +03:00
case AOT_ER_BSAC :
skip_bits ( gb , 5 ) ; // numOfSubFrame
skip_bits ( gb , 11 ) ; // layer_length
break ;
case AOT_ER_AAC_LC :
case AOT_ER_AAC_LTP :
case AOT_ER_AAC_SCALABLE :
case AOT_ER_AAC_LD :
skip_bits ( gb , 3 ) ; /* aacSectionDataResilienceFlag
2008-08-11 14:16:06 +03:00
* aacScalefactorDataResilienceFlag
* aacSpectralDataResilienceFlag
*/
2009-08-02 13:50:59 +03:00
break ;
2008-08-11 14:16:06 +03:00
}
skip_bits1 ( gb ) ; // extensionFlag3 (TBD in version 3)
}
return 0 ;
}
/**
* Decode audio specific configuration ; reference : table 1.13 .
*
* @ param data pointer to AVCodecContext extradata
* @ param data_size size of AVCCodecContext extradata
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_audio_specific_config ( AACContext * ac , void * data ,
int data_size )
{
2008-08-11 14:16:06 +03:00
GetBitContext gb ;
int i ;
init_get_bits ( & gb , data , data_size * 8 ) ;
2009-08-02 13:50:59 +03:00
if ( ( i = ff_mpeg4audio_get_config ( & ac - > m4ac , data , data_size ) ) < 0 )
2008-08-11 14:16:06 +03:00
return - 1 ;
2009-08-02 13:50:59 +03:00
if ( ac - > m4ac . sampling_index > 12 ) {
2008-08-11 14:16:06 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " invalid sampling rate index %d \n " , ac - > m4ac . sampling_index ) ;
return - 1 ;
}
skip_bits_long ( & gb , i ) ;
switch ( ac - > m4ac . object_type ) {
2008-11-24 02:13:50 +02:00
case AOT_AAC_MAIN :
2008-08-11 14:16:06 +03:00
case AOT_AAC_LC :
if ( decode_ga_specific_config ( ac , & gb , ac - > m4ac . chan_config ) )
return - 1 ;
break ;
default :
av_log ( ac - > avccontext , AV_LOG_ERROR , " Audio object type %s%d is not supported. \n " ,
ac - > m4ac . sbr = = 1 ? " SBR+ " : " " , ac - > m4ac . object_type ) ;
return - 1 ;
}
return 0 ;
}
2008-08-15 03:05:09 +03:00
/**
* linear congruential pseudorandom number generator
*
* @ param previous_val pointer to the current state of the generator
*
* @ return Returns a 32 - bit pseudorandom integer
*/
2009-08-02 13:50:59 +03:00
static av_always_inline int lcg_random ( int previous_val )
{
2008-08-15 03:05:09 +03:00
return previous_val * 1664525 + 1013904223 ;
}
2009-08-02 13:50:59 +03:00
static void reset_predict_state ( PredictorState * ps )
{
ps - > r0 = 0.0f ;
ps - > r1 = 0.0f ;
2008-11-24 02:13:50 +02:00
ps - > cor0 = 0.0f ;
ps - > cor1 = 0.0f ;
ps - > var0 = 1.0f ;
ps - > var1 = 1.0f ;
}
2009-08-02 13:50:59 +03:00
static void reset_all_predictors ( PredictorState * ps )
{
2008-11-24 02:13:50 +02:00
int i ;
for ( i = 0 ; i < MAX_PREDICTORS ; i + + )
reset_predict_state ( & ps [ i ] ) ;
}
2009-08-02 13:50:59 +03:00
static void reset_predictor_group ( PredictorState * ps , int group_num )
{
2008-11-24 02:13:50 +02:00
int i ;
2009-08-02 13:50:59 +03:00
for ( i = group_num - 1 ; i < MAX_PREDICTORS ; i + = 30 )
2008-11-24 02:13:50 +02:00
reset_predict_state ( & ps [ i ] ) ;
}
2009-08-02 13:50:59 +03:00
static av_cold int aac_decode_init ( AVCodecContext * avccontext )
{
AACContext * ac = avccontext - > priv_data ;
2008-08-05 22:32:01 +03:00
int i ;
ac - > avccontext = avccontext ;
2009-01-08 00:09:21 +02:00
if ( avccontext - > extradata_size > 0 ) {
2009-08-02 13:50:59 +03:00
if ( decode_audio_specific_config ( ac , avccontext - > extradata , avccontext - > extradata_size ) )
2009-01-08 00:09:21 +02:00
return - 1 ;
avccontext - > sample_rate = ac - > m4ac . sample_rate ;
} else if ( avccontext - > channels > 0 ) {
ac - > m4ac . sample_rate = avccontext - > sample_rate ;
}
2008-08-09 13:46:27 +03:00
2009-08-02 13:50:59 +03:00
avccontext - > sample_fmt = SAMPLE_FMT_S16 ;
avccontext - > frame_size = 1024 ;
2008-08-05 22:32:01 +03:00
2010-01-13 18:46:39 +02:00
AAC_INIT_VLC_STATIC ( 0 , 304 ) ;
AAC_INIT_VLC_STATIC ( 1 , 270 ) ;
AAC_INIT_VLC_STATIC ( 2 , 550 ) ;
AAC_INIT_VLC_STATIC ( 3 , 300 ) ;
AAC_INIT_VLC_STATIC ( 4 , 328 ) ;
AAC_INIT_VLC_STATIC ( 5 , 294 ) ;
AAC_INIT_VLC_STATIC ( 6 , 306 ) ;
AAC_INIT_VLC_STATIC ( 7 , 268 ) ;
AAC_INIT_VLC_STATIC ( 8 , 510 ) ;
AAC_INIT_VLC_STATIC ( 9 , 366 ) ;
AAC_INIT_VLC_STATIC ( 10 , 462 ) ;
2008-08-05 22:32:01 +03:00
dsputil_init ( & ac - > dsp , avccontext ) ;
2008-08-11 14:16:06 +03:00
ac - > random_state = 0x1f2e3d4c ;
2008-08-05 22:32:01 +03:00
// -1024 - Compensate wrong IMDCT method.
// 32768 - Required to scale values to the correct range for the bias method
// for float to int16 conversion.
2009-10-08 17:40:14 +03:00
if ( ac - > dsp . float_to_int16_interleave = = ff_float_to_int16_interleave_c ) {
2009-08-02 13:50:59 +03:00
ac - > add_bias = 385.0f ;
ac - > sf_scale = 1. / ( - 1024. * 32768. ) ;
2008-08-05 22:32:01 +03:00
ac - > sf_offset = 0 ;
} else {
2009-08-02 13:50:59 +03:00
ac - > add_bias = 0.0f ;
ac - > sf_scale = 1. / - 1024. ;
2008-08-05 22:32:01 +03:00
ac - > sf_offset = 60 ;
}
2009-01-14 01:44:16 +02:00
# if !CONFIG_HARDCODED_TABLES
2008-11-05 15:59:42 +02:00
for ( i = 0 ; i < 428 ; i + + )
2009-08-02 13:50:59 +03:00
ff_aac_pow2sf_tab [ i ] = pow ( 2 , ( i - 200 ) / 4. ) ;
2008-08-05 22:32:01 +03:00
# endif /* CONFIG_HARDCODED_TABLES */
2008-10-22 00:40:24 +03:00
INIT_VLC_STATIC ( & vlc_scalefactors , 7 , FF_ARRAY_ELEMS ( ff_aac_scalefactor_code ) ,
2009-08-02 13:50:59 +03:00
ff_aac_scalefactor_bits , sizeof ( ff_aac_scalefactor_bits [ 0 ] ) , sizeof ( ff_aac_scalefactor_bits [ 0 ] ) ,
ff_aac_scalefactor_code , sizeof ( ff_aac_scalefactor_code [ 0 ] ) , sizeof ( ff_aac_scalefactor_code [ 0 ] ) ,
352 ) ;
2008-08-05 22:32:01 +03:00
2009-05-16 17:17:08 +03:00
ff_mdct_init ( & ac - > mdct , 11 , 1 , 1.0 ) ;
ff_mdct_init ( & ac - > mdct_small , 8 , 1 , 1.0 ) ;
2008-08-15 11:01:31 +03:00
// window initialization
ff_kbd_window_init ( ff_aac_kbd_long_1024 , 4.0 , 1024 ) ;
ff_kbd_window_init ( ff_aac_kbd_short_128 , 6.0 , 128 ) ;
2010-01-09 15:28:04 +02:00
ff_init_ff_sine_windows ( 10 ) ;
ff_init_ff_sine_windows ( 7 ) ;
2008-08-15 11:01:31 +03:00
2010-01-13 18:46:28 +02:00
if ( ! cbrt_tab [ ( 1 < < 13 ) - 1 ] ) {
for ( i = 0 ; i < 1 < < 13 ; i + + ) {
union float754 f ;
f . f = cbrtf ( i ) * i ;
cbrt_tab [ i ] = f . i ;
}
}
2010-01-11 22:21:26 +02:00
2008-08-05 22:32:01 +03:00
return 0 ;
}
2008-08-11 14:16:06 +03:00
/**
* Skip data_stream_element ; reference : table 4.10 .
*/
2009-08-02 13:50:59 +03:00
static void skip_data_stream_element ( GetBitContext * gb )
{
2008-08-05 22:32:01 +03:00
int byte_align = get_bits1 ( gb ) ;
int count = get_bits ( gb , 8 ) ;
if ( count = = 255 )
count + = get_bits ( gb , 8 ) ;
if ( byte_align )
align_get_bits ( gb ) ;
skip_bits_long ( gb , 8 * count ) ;
}
2009-08-02 13:50:59 +03:00
static int decode_prediction ( AACContext * ac , IndividualChannelStream * ics ,
GetBitContext * gb )
{
2008-11-24 02:13:50 +02:00
int sfb ;
if ( get_bits1 ( gb ) ) {
ics - > predictor_reset_group = get_bits ( gb , 5 ) ;
if ( ics - > predictor_reset_group = = 0 | | ics - > predictor_reset_group > 30 ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " Invalid Predictor Reset Group. \n " ) ;
return - 1 ;
}
}
for ( sfb = 0 ; sfb < FFMIN ( ics - > max_sfb , ff_aac_pred_sfb_max [ ac - > m4ac . sampling_index ] ) ; sfb + + ) {
ics - > prediction_used [ sfb ] = get_bits1 ( gb ) ;
}
return 0 ;
}
2008-08-11 14:16:06 +03:00
/**
* Decode Individual Channel Stream info ; reference : table 4.6 .
*
* @ param common_window Channels have independent [ 0 ] , or shared [ 1 ] , Individual Channel Stream information .
*/
2009-08-02 13:50:59 +03:00
static int decode_ics_info ( AACContext * ac , IndividualChannelStream * ics ,
GetBitContext * gb , int common_window )
{
2008-08-11 14:16:06 +03:00
if ( get_bits1 ( gb ) ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " Reserved bit set. \n " ) ;
memset ( ics , 0 , sizeof ( IndividualChannelStream ) ) ;
return - 1 ;
}
ics - > window_sequence [ 1 ] = ics - > window_sequence [ 0 ] ;
ics - > window_sequence [ 0 ] = get_bits ( gb , 2 ) ;
2009-08-02 13:50:59 +03:00
ics - > use_kb_window [ 1 ] = ics - > use_kb_window [ 0 ] ;
ics - > use_kb_window [ 0 ] = get_bits1 ( gb ) ;
ics - > num_window_groups = 1 ;
ics - > group_len [ 0 ] = 1 ;
2008-08-15 11:01:31 +03:00
if ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) {
int i ;
ics - > max_sfb = get_bits ( gb , 4 ) ;
for ( i = 0 ; i < 7 ; i + + ) {
if ( get_bits1 ( gb ) ) {
2009-08-02 13:50:59 +03:00
ics - > group_len [ ics - > num_window_groups - 1 ] + + ;
2008-08-15 11:01:31 +03:00
} else {
ics - > num_window_groups + + ;
2009-08-02 13:50:59 +03:00
ics - > group_len [ ics - > num_window_groups - 1 ] = 1 ;
2008-08-15 11:01:31 +03:00
}
}
2009-08-02 13:50:59 +03:00
ics - > num_windows = 8 ;
ics - > swb_offset = ff_swb_offset_128 [ ac - > m4ac . sampling_index ] ;
ics - > num_swb = ff_aac_num_swb_128 [ ac - > m4ac . sampling_index ] ;
ics - > tns_max_bands = ff_tns_max_bands_128 [ ac - > m4ac . sampling_index ] ;
2008-11-24 02:13:50 +02:00
ics - > predictor_present = 0 ;
2008-08-15 11:01:31 +03:00
} else {
2009-08-02 13:50:59 +03:00
ics - > max_sfb = get_bits ( gb , 6 ) ;
ics - > num_windows = 1 ;
ics - > swb_offset = ff_swb_offset_1024 [ ac - > m4ac . sampling_index ] ;
ics - > num_swb = ff_aac_num_swb_1024 [ ac - > m4ac . sampling_index ] ;
ics - > tns_max_bands = ff_tns_max_bands_1024 [ ac - > m4ac . sampling_index ] ;
ics - > predictor_present = get_bits1 ( gb ) ;
2008-11-24 02:13:50 +02:00
ics - > predictor_reset_group = 0 ;
if ( ics - > predictor_present ) {
if ( ac - > m4ac . object_type = = AOT_AAC_MAIN ) {
if ( decode_prediction ( ac , ics , gb ) ) {
memset ( ics , 0 , sizeof ( IndividualChannelStream ) ) ;
return - 1 ;
}
} else if ( ac - > m4ac . object_type = = AOT_AAC_LC ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " Prediction is not allowed in AAC-LC. \n " ) ;
memset ( ics , 0 , sizeof ( IndividualChannelStream ) ) ;
return - 1 ;
} else {
2009-06-29 22:07:04 +03:00
av_log_missing_feature ( ac - > avccontext , " Predictor bit set but LTP is " , 1 ) ;
2008-11-24 02:14:33 +02:00
memset ( ics , 0 , sizeof ( IndividualChannelStream ) ) ;
return - 1 ;
2008-11-24 02:13:50 +02:00
}
2008-08-15 03:05:09 +03:00
}
}
2009-08-02 13:50:59 +03:00
if ( ics - > max_sfb > ics - > num_swb ) {
2008-08-15 03:05:09 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
2009-08-02 13:50:59 +03:00
" Number of scalefactor bands in group (%d) exceeds limit (%d). \n " ,
ics - > max_sfb , ics - > num_swb ) ;
2008-08-15 03:05:09 +03:00
memset ( ics , 0 , sizeof ( IndividualChannelStream ) ) ;
return - 1 ;
}
2008-08-11 14:16:06 +03:00
return 0 ;
}
/**
* Decode band types ( section_data payload ) ; reference : table 4.46 .
*
* @ param band_type array of the used band type
* @ param band_type_run_end array of the last scalefactor band of a band type run
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_band_types ( AACContext * ac , enum BandType band_type [ 120 ] ,
int band_type_run_end [ 120 ] , GetBitContext * gb ,
IndividualChannelStream * ics )
{
2008-08-09 13:46:27 +03:00
int g , idx = 0 ;
const int bits = ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) ? 3 : 5 ;
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
int k = 0 ;
while ( k < ics - > max_sfb ) {
2009-11-11 22:33:56 +02:00
uint8_t sect_end = k ;
2008-08-09 13:46:27 +03:00
int sect_len_incr ;
int sect_band_type = get_bits ( gb , 4 ) ;
if ( sect_band_type = = 12 ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " invalid band type \n " ) ;
return - 1 ;
}
2009-08-02 13:50:59 +03:00
while ( ( sect_len_incr = get_bits ( gb , bits ) ) = = ( 1 < < bits ) - 1 )
2009-11-11 22:33:56 +02:00
sect_end + = sect_len_incr ;
sect_end + = sect_len_incr ;
if ( sect_end > ics - > max_sfb ) {
2008-08-09 13:46:27 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
2009-08-02 13:50:59 +03:00
" Number of bands (%d) exceeds limit (%d). \n " ,
2009-11-11 22:33:56 +02:00
sect_end , ics - > max_sfb ) ;
2008-08-09 13:46:27 +03:00
return - 1 ;
}
2009-11-11 22:33:56 +02:00
for ( ; k < sect_end ; k + + ) {
2008-08-15 11:01:31 +03:00
band_type [ idx ] = sect_band_type ;
2009-11-11 22:33:56 +02:00
band_type_run_end [ idx + + ] = sect_end ;
2008-08-15 11:01:31 +03:00
}
2008-08-11 14:16:06 +03:00
}
}
return 0 ;
}
2008-08-09 13:46:27 +03:00
2008-08-11 14:16:06 +03:00
/**
* Decode scalefactors ; reference : table 4.47 .
2008-08-09 13:46:27 +03:00
*
* @ param global_gain first scalefactor value as scalefactors are differentially coded
* @ param band_type array of the used band type
* @ param band_type_run_end array of the last scalefactor band of a band type run
* @ param sf array of scalefactors or intensity stereo positions
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_scalefactors ( AACContext * ac , float sf [ 120 ] , GetBitContext * gb ,
unsigned int global_gain ,
IndividualChannelStream * ics ,
enum BandType band_type [ 120 ] ,
int band_type_run_end [ 120 ] )
{
2008-08-09 13:46:27 +03:00
const int sf_offset = ac - > sf_offset + ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ? 12 : 0 ) ;
int g , i , idx = 0 ;
int offset [ 3 ] = { global_gain , global_gain - 90 , 100 } ;
int noise_flag = 1 ;
static const char * sf_str [ 3 ] = { " Global gain " , " Noise gain " , " Intensity stereo position " } ;
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
for ( i = 0 ; i < ics - > max_sfb ; ) {
int run_end = band_type_run_end [ idx ] ;
if ( band_type [ idx ] = = ZERO_BT ) {
2009-08-02 13:50:59 +03:00
for ( ; i < run_end ; i + + , idx + + )
2008-08-09 13:46:27 +03:00
sf [ idx ] = 0. ;
2009-08-02 13:50:59 +03:00
} else if ( ( band_type [ idx ] = = INTENSITY_BT ) | | ( band_type [ idx ] = = INTENSITY_BT2 ) ) {
for ( ; i < run_end ; i + + , idx + + ) {
2008-08-09 13:46:27 +03:00
offset [ 2 ] + = get_vlc2 ( gb , vlc_scalefactors . table , 7 , 3 ) - 60 ;
2009-08-02 13:50:59 +03:00
if ( offset [ 2 ] > 255U ) {
2008-08-09 13:46:27 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
2009-08-02 13:50:59 +03:00
" %s (%d) out of range. \n " , sf_str [ 2 ] , offset [ 2 ] ) ;
2008-08-09 13:46:27 +03:00
return - 1 ;
}
2009-08-02 13:50:59 +03:00
sf [ idx ] = ff_aac_pow2sf_tab [ - offset [ 2 ] + 300 ] ;
2008-08-09 13:46:27 +03:00
}
2009-08-02 13:50:59 +03:00
} else if ( band_type [ idx ] = = NOISE_BT ) {
for ( ; i < run_end ; i + + , idx + + ) {
if ( noise_flag - - > 0 )
2008-08-09 13:46:27 +03:00
offset [ 1 ] + = get_bits ( gb , 9 ) - 256 ;
else
offset [ 1 ] + = get_vlc2 ( gb , vlc_scalefactors . table , 7 , 3 ) - 60 ;
2009-08-02 13:50:59 +03:00
if ( offset [ 1 ] > 255U ) {
2008-08-09 13:46:27 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
2009-08-02 13:50:59 +03:00
" %s (%d) out of range. \n " , sf_str [ 1 ] , offset [ 1 ] ) ;
2008-08-09 13:46:27 +03:00
return - 1 ;
}
2009-08-02 13:50:59 +03:00
sf [ idx ] = - ff_aac_pow2sf_tab [ offset [ 1 ] + sf_offset + 100 ] ;
2008-08-09 13:46:27 +03:00
}
2009-08-02 13:50:59 +03:00
} else {
for ( ; i < run_end ; i + + , idx + + ) {
2008-08-09 13:46:27 +03:00
offset [ 0 ] + = get_vlc2 ( gb , vlc_scalefactors . table , 7 , 3 ) - 60 ;
2009-08-02 13:50:59 +03:00
if ( offset [ 0 ] > 255U ) {
2008-08-09 13:46:27 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
2009-08-02 13:50:59 +03:00
" %s (%d) out of range. \n " , sf_str [ 0 ] , offset [ 0 ] ) ;
2008-08-09 13:46:27 +03:00
return - 1 ;
}
sf [ idx ] = - ff_aac_pow2sf_tab [ offset [ 0 ] + sf_offset ] ;
}
}
}
}
return 0 ;
}
/**
* Decode pulse data ; reference : table 4.7 .
*/
2009-08-02 13:50:59 +03:00
static int decode_pulses ( Pulse * pulse , GetBitContext * gb ,
const uint16_t * swb_offset , int num_swb )
{
2008-09-16 18:59:43 +03:00
int i , pulse_swb ;
2008-08-09 13:46:27 +03:00
pulse - > num_pulse = get_bits ( gb , 2 ) + 1 ;
2008-09-16 18:59:43 +03:00
pulse_swb = get_bits ( gb , 6 ) ;
if ( pulse_swb > = num_swb )
return - 1 ;
pulse - > pos [ 0 ] = swb_offset [ pulse_swb ] ;
2008-09-13 23:22:31 +03:00
pulse - > pos [ 0 ] + = get_bits ( gb , 5 ) ;
2008-09-16 18:59:43 +03:00
if ( pulse - > pos [ 0 ] > 1023 )
return - 1 ;
2008-08-15 03:19:14 +03:00
pulse - > amp [ 0 ] = get_bits ( gb , 4 ) ;
for ( i = 1 ; i < pulse - > num_pulse ; i + + ) {
2009-08-02 13:50:59 +03:00
pulse - > pos [ i ] = get_bits ( gb , 5 ) + pulse - > pos [ i - 1 ] ;
2008-09-16 18:59:43 +03:00
if ( pulse - > pos [ i ] > 1023 )
return - 1 ;
2008-08-15 03:19:14 +03:00
pulse - > amp [ i ] = get_bits ( gb , 4 ) ;
2008-08-09 13:46:27 +03:00
}
2008-09-16 18:59:43 +03:00
return 0 ;
2008-08-09 13:46:27 +03:00
}
2008-08-19 00:36:58 +03:00
/**
* Decode Temporal Noise Shaping data ; reference : table 4.48 .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_tns ( AACContext * ac , TemporalNoiseShaping * tns ,
GetBitContext * gb , const IndividualChannelStream * ics )
{
2008-08-19 00:36:58 +03:00
int w , filt , i , coef_len , coef_res , coef_compress ;
const int is8 = ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ;
const int tns_max_order = is8 ? 7 : ac - > m4ac . object_type = = AOT_AAC_MAIN ? 20 : 12 ;
for ( w = 0 ; w < ics - > num_windows ; w + + ) {
2008-08-21 15:12:03 +03:00
if ( ( tns - > n_filt [ w ] = get_bits ( gb , 2 - is8 ) ) ) {
2008-08-19 00:36:58 +03:00
coef_res = get_bits1 ( gb ) ;
2008-08-21 15:13:22 +03:00
for ( filt = 0 ; filt < tns - > n_filt [ w ] ; filt + + ) {
int tmp2_idx ;
2009-08-02 13:50:59 +03:00
tns - > length [ w ] [ filt ] = get_bits ( gb , 6 - 2 * is8 ) ;
2008-08-21 15:13:22 +03:00
2009-08-02 13:50:59 +03:00
if ( ( tns - > order [ w ] [ filt ] = get_bits ( gb , 5 - 2 * is8 ) ) > tns_max_order ) {
2008-08-21 15:13:22 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " TNS filter order %d is greater than maximum %d. " ,
tns - > order [ w ] [ filt ] , tns_max_order ) ;
tns - > order [ w ] [ filt ] = 0 ;
return - 1 ;
}
2008-09-12 17:32:49 +03:00
if ( tns - > order [ w ] [ filt ] ) {
2008-09-12 17:33:35 +03:00
tns - > direction [ w ] [ filt ] = get_bits1 ( gb ) ;
coef_compress = get_bits1 ( gb ) ;
coef_len = coef_res + 3 - coef_compress ;
2009-08-02 13:50:59 +03:00
tmp2_idx = 2 * coef_compress + coef_res ;
2008-08-19 00:36:58 +03:00
2008-09-12 17:33:35 +03:00
for ( i = 0 ; i < tns - > order [ w ] [ filt ] ; i + + )
tns - > coef [ w ] [ filt ] [ i ] = tns_tmp2_map [ tmp2_idx ] [ get_bits ( gb , coef_len ) ] ;
2008-09-12 17:32:49 +03:00
}
2008-08-21 15:13:22 +03:00
}
2008-08-21 15:12:03 +03:00
}
2008-08-19 00:36:58 +03:00
}
return 0 ;
}
2008-08-11 14:16:06 +03:00
/**
* Decode Mid / Side data ; reference : table 4.54 .
*
* @ param ms_present Indicates mid / side stereo presence . [ 0 ] mask is all 0 s ;
* [ 1 ] mask is decoded from bitstream ; [ 2 ] mask is all 1 s ;
* [ 3 ] reserved for scalable AAC
*/
2009-08-02 13:50:59 +03:00
static void decode_mid_side_stereo ( ChannelElement * cpe , GetBitContext * gb ,
int ms_present )
{
2008-08-15 03:05:09 +03:00
int idx ;
if ( ms_present = = 1 ) {
for ( idx = 0 ; idx < cpe - > ch [ 0 ] . ics . num_window_groups * cpe - > ch [ 0 ] . ics . max_sfb ; idx + + )
cpe - > ms_mask [ idx ] = get_bits1 ( gb ) ;
} else if ( ms_present = = 2 ) {
memset ( cpe - > ms_mask , 1 , cpe - > ch [ 0 ] . ics . num_window_groups * cpe - > ch [ 0 ] . ics . max_sfb * sizeof ( cpe - > ms_mask [ 0 ] ) ) ;
}
}
2008-08-11 14:16:06 +03:00
2010-01-15 04:58:24 +02:00
# ifndef VMUL2
2010-01-13 18:46:28 +02:00
static inline float * VMUL2 ( float * dst , const float * v , unsigned idx ,
const float * scale )
{
float s = * scale ;
* dst + + = v [ idx & 15 ] * s ;
* dst + + = v [ idx > > 4 & 15 ] * s ;
return dst ;
}
2010-01-15 04:58:24 +02:00
# endif
2010-01-13 18:46:28 +02:00
2010-01-15 04:58:24 +02:00
# ifndef VMUL4
2010-01-13 18:46:28 +02:00
static inline float * VMUL4 ( float * dst , const float * v , unsigned idx ,
const float * scale )
{
float s = * scale ;
* dst + + = v [ idx & 3 ] * s ;
* dst + + = v [ idx > > 2 & 3 ] * s ;
* dst + + = v [ idx > > 4 & 3 ] * s ;
* dst + + = v [ idx > > 6 & 3 ] * s ;
return dst ;
}
2010-01-15 04:58:24 +02:00
# endif
2010-01-13 18:46:28 +02:00
2010-01-15 04:58:24 +02:00
# ifndef VMUL2S
2010-01-13 18:46:28 +02:00
static inline float * VMUL2S ( float * dst , const float * v , unsigned idx ,
unsigned sign , const float * scale )
{
union float754 s0 , s1 ;
s0 . f = s1 . f = * scale ;
s0 . i ^ = sign > > 1 < < 31 ;
s1 . i ^ = sign < < 31 ;
* dst + + = v [ idx & 15 ] * s0 . f ;
* dst + + = v [ idx > > 4 & 15 ] * s1 . f ;
return dst ;
}
2010-01-15 04:58:24 +02:00
# endif
2010-01-13 18:46:28 +02:00
2010-01-15 04:58:24 +02:00
# ifndef VMUL4S
2010-01-13 18:46:28 +02:00
static inline float * VMUL4S ( float * dst , const float * v , unsigned idx ,
unsigned sign , const float * scale )
{
unsigned nz = idx > > 12 ;
union float754 s = { . f = * scale } ;
union float754 t ;
t . i = s . i ^ ( sign & 1 < < 31 ) ;
* dst + + = v [ idx & 3 ] * t . f ;
sign < < = nz & 1 ; nz > > = 1 ;
t . i = s . i ^ ( sign & 1 < < 31 ) ;
* dst + + = v [ idx > > 2 & 3 ] * t . f ;
sign < < = nz & 1 ; nz > > = 1 ;
t . i = s . i ^ ( sign & 1 < < 31 ) ;
* dst + + = v [ idx > > 4 & 3 ] * t . f ;
sign < < = nz & 1 ; nz > > = 1 ;
t . i = s . i ^ ( sign & 1 < < 31 ) ;
* dst + + = v [ idx > > 6 & 3 ] * t . f ;
return dst ;
}
2010-01-15 04:58:24 +02:00
# endif
2010-01-13 18:46:28 +02:00
2008-08-15 11:01:31 +03:00
/**
* Decode spectral data ; reference : table 4.50 .
* Dequantize and scale spectral data ; reference : 4.6 .3 .3 .
*
* @ param coef array of dequantized , scaled spectral data
* @ param sf array of scalefactors or intensity stereo positions
* @ param pulse_present set if pulses are present
* @ param pulse pointer to pulse data struct
* @ param band_type array of the used band type
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_spectrum_and_dequant ( AACContext * ac , float coef [ 1024 ] ,
2010-01-08 19:52:54 +02:00
GetBitContext * gb , const float sf [ 120 ] ,
2009-08-02 13:50:59 +03:00
int pulse_present , const Pulse * pulse ,
const IndividualChannelStream * ics ,
enum BandType band_type [ 120 ] )
{
2008-08-15 11:01:31 +03:00
int i , k , g , idx = 0 ;
2009-08-02 13:50:59 +03:00
const int c = 1024 / ics - > num_windows ;
const uint16_t * offsets = ics - > swb_offset ;
2008-08-15 11:01:31 +03:00
float * coef_base = coef ;
2010-01-13 18:46:28 +02:00
int err_idx ;
2008-08-15 11:01:31 +03:00
for ( g = 0 ; g < ics - > num_windows ; g + + )
2009-08-02 13:50:59 +03:00
memset ( coef + g * 128 + offsets [ ics - > max_sfb ] , 0 , sizeof ( float ) * ( c - offsets [ ics - > max_sfb ] ) ) ;
2008-08-15 11:01:31 +03:00
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
2010-01-13 18:46:32 +02:00
unsigned g_len = ics - > group_len [ g ] ;
2008-08-15 11:01:31 +03:00
for ( i = 0 ; i < ics - > max_sfb ; i + + , idx + + ) {
2010-01-13 18:46:32 +02:00
const unsigned cbt_m1 = band_type [ idx ] - 1 ;
float * cfo = coef + offsets [ i ] ;
int off_len = offsets [ i + 1 ] - offsets [ i ] ;
2008-08-15 11:01:31 +03:00
int group ;
2010-01-13 18:46:32 +02:00
if ( cbt_m1 > = INTENSITY_BT2 - 1 ) {
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
memset ( cfo , 0 , off_len * sizeof ( float ) ) ;
2008-08-15 11:01:31 +03:00
}
2010-01-13 18:46:32 +02:00
} else if ( cbt_m1 = = NOISE_BT - 1 ) {
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
2008-11-05 15:59:42 +02:00
float scale ;
2009-09-23 16:52:53 +03:00
float band_energy ;
2009-09-22 03:48:45 +03:00
2010-01-13 18:46:32 +02:00
for ( k = 0 ; k < off_len ; k + + ) {
2008-08-15 11:01:31 +03:00
ac - > random_state = lcg_random ( ac - > random_state ) ;
2010-01-13 18:46:32 +02:00
cfo [ k ] = ac - > random_state ;
2008-11-05 15:59:42 +02:00
}
2009-09-22 03:48:45 +03:00
2010-01-13 18:46:32 +02:00
band_energy = ac - > dsp . scalarproduct_float ( cfo , cfo , off_len ) ;
2008-11-05 15:59:42 +02:00
scale = sf [ idx ] / sqrtf ( band_energy ) ;
2010-01-13 18:46:32 +02:00
ac - > dsp . vector_fmul_scalar ( cfo , cfo , scale , off_len ) ;
2008-08-15 11:01:31 +03:00
}
2009-08-02 13:50:59 +03:00
} else {
2010-01-13 18:46:32 +02:00
const float * vq = ff_aac_codebook_vector_vals [ cbt_m1 ] ;
const uint16_t * cb_vector_idx = ff_aac_codebook_vector_idx [ cbt_m1 ] ;
VLC_TYPE ( * vlc_tab ) [ 2 ] = vlc_spectral [ cbt_m1 ] . table ;
const int cb_size = ff_aac_spectral_sizes [ cbt_m1 ] ;
2010-01-15 16:02:52 +02:00
OPEN_READER ( re , gb ) ;
2010-01-13 18:46:28 +02:00
2010-01-13 18:46:35 +02:00
switch ( cbt_m1 > > 1 ) {
case 0 :
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
float * cf = cfo ;
int len = off_len ;
2009-09-22 03:48:45 +03:00
2010-01-13 18:46:28 +02:00
do {
2010-01-15 16:02:52 +02:00
int code ;
2010-01-13 18:46:28 +02:00
unsigned cb_idx ;
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
GET_VLC ( code , re , gb , vlc_tab , 8 , 2 ) ;
if ( code > = cb_size ) {
err_idx = code ;
2010-01-13 18:46:28 +02:00
goto err_cb_overflow ;
}
2010-01-15 16:02:52 +02:00
cb_idx = cb_vector_idx [ code ] ;
2010-01-13 18:46:28 +02:00
cf = VMUL4 ( cf , vq , cb_idx , sf + idx ) ;
} while ( len - = 4 ) ;
2010-01-13 18:46:35 +02:00
}
break ;
case 1 :
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
float * cf = cfo ;
int len = off_len ;
2010-01-13 18:46:28 +02:00
do {
2010-01-15 16:02:52 +02:00
int code ;
2010-01-13 18:46:28 +02:00
unsigned nnz ;
unsigned cb_idx ;
uint32_t bits ;
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
GET_VLC ( code , re , gb , vlc_tab , 8 , 2 ) ;
if ( code > = cb_size ) {
err_idx = code ;
2010-01-13 18:46:28 +02:00
goto err_cb_overflow ;
}
2010-01-15 16:02:52 +02:00
# if MIN_CACHE_BITS < 20
UPDATE_CACHE ( re , gb ) ;
# endif
cb_idx = cb_vector_idx [ code ] ;
2010-01-13 18:46:28 +02:00
nnz = cb_idx > > 8 & 15 ;
2010-01-15 16:02:52 +02:00
bits = SHOW_UBITS ( re , gb , nnz ) < < ( 32 - nnz ) ;
LAST_SKIP_BITS ( re , gb , nnz ) ;
2010-01-13 18:46:28 +02:00
cf = VMUL4S ( cf , vq , cb_idx , bits , sf + idx ) ;
} while ( len - = 4 ) ;
2010-01-13 18:46:35 +02:00
}
break ;
case 2 :
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
float * cf = cfo ;
int len = off_len ;
2010-01-13 18:46:28 +02:00
do {
2010-01-15 16:02:52 +02:00
int code ;
2010-01-13 18:46:28 +02:00
unsigned cb_idx ;
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
GET_VLC ( code , re , gb , vlc_tab , 8 , 2 ) ;
if ( code > = cb_size ) {
err_idx = code ;
2010-01-13 18:46:28 +02:00
goto err_cb_overflow ;
2008-12-09 19:08:40 +02:00
}
2010-01-13 18:46:28 +02:00
2010-01-15 16:02:52 +02:00
cb_idx = cb_vector_idx [ code ] ;
2010-01-13 18:46:28 +02:00
cf = VMUL2 ( cf , vq , cb_idx , sf + idx ) ;
} while ( len - = 2 ) ;
2010-01-13 18:46:35 +02:00
}
break ;
case 3 :
case 4 :
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
float * cf = cfo ;
int len = off_len ;
2010-01-13 18:46:28 +02:00
do {
2010-01-15 16:02:52 +02:00
int code ;
2010-01-13 18:46:28 +02:00
unsigned nnz ;
unsigned cb_idx ;
unsigned sign ;
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
GET_VLC ( code , re , gb , vlc_tab , 8 , 2 ) ;
if ( code > = cb_size ) {
err_idx = code ;
2010-01-13 18:46:28 +02:00
goto err_cb_overflow ;
}
2010-01-15 16:02:52 +02:00
cb_idx = cb_vector_idx [ code ] ;
2010-01-13 18:46:28 +02:00
nnz = cb_idx > > 8 & 15 ;
2010-01-15 16:02:52 +02:00
sign = SHOW_UBITS ( re , gb , nnz ) < < ( cb_idx > > 12 ) ;
LAST_SKIP_BITS ( re , gb , nnz ) ;
2010-01-13 18:46:28 +02:00
cf = VMUL2S ( cf , vq , cb_idx , sign , sf + idx ) ;
} while ( len - = 2 ) ;
2010-01-13 18:46:35 +02:00
}
break ;
default :
for ( group = 0 ; group < g_len ; group + + , cfo + = 128 ) {
float * cf = cfo ;
uint32_t * icf = ( uint32_t * ) cf ;
int len = off_len ;
2010-01-13 18:46:32 +02:00
do {
2010-01-15 16:02:52 +02:00
int code ;
2010-01-13 18:46:28 +02:00
unsigned nzt , nnz ;
unsigned cb_idx ;
uint32_t bits ;
int j ;
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
GET_VLC ( code , re , gb , vlc_tab , 8 , 2 ) ;
if ( ! code ) {
2010-01-13 18:46:32 +02:00
* icf + + = 0 ;
* icf + + = 0 ;
2010-01-13 18:46:28 +02:00
continue ;
}
2010-01-15 16:02:52 +02:00
if ( code > = cb_size ) {
err_idx = code ;
2010-01-13 18:46:28 +02:00
goto err_cb_overflow ;
}
2010-01-15 16:02:52 +02:00
cb_idx = cb_vector_idx [ code ] ;
2010-01-13 18:46:28 +02:00
nnz = cb_idx > > 12 ;
nzt = cb_idx > > 8 ;
2010-01-15 16:02:52 +02:00
bits = SHOW_UBITS ( re , gb , nnz ) < < ( 32 - nnz ) ;
LAST_SKIP_BITS ( re , gb , nnz ) ;
2010-01-13 18:46:28 +02:00
for ( j = 0 ; j < 2 ; j + + ) {
if ( nzt & 1 < < j ) {
2010-01-15 16:02:52 +02:00
uint32_t b ;
int n ;
2010-01-13 18:46:28 +02:00
/* The total length of escape_sequence must be < 22 bits according
to the specification ( i . e . max is 111111110 xxxxxxxxxxxx ) . */
2010-01-15 16:02:52 +02:00
UPDATE_CACHE ( re , gb ) ;
b = GET_CACHE ( re , gb ) ;
b = 31 - av_log2 ( ~ b ) ;
if ( b > 8 ) {
2010-01-13 18:46:28 +02:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " error in spectral data, ESC overflow \n " ) ;
return - 1 ;
}
2010-01-15 16:02:52 +02:00
# if MIN_CACHE_BITS < 21
LAST_SKIP_BITS ( re , gb , b + 1 ) ;
UPDATE_CACHE ( re , gb ) ;
# else
SKIP_BITS ( re , gb , b + 1 ) ;
# endif
b + = 4 ;
n = ( 1 < < b ) + SHOW_UBITS ( re , gb , b ) ;
LAST_SKIP_BITS ( re , gb , b ) ;
2010-01-13 18:46:32 +02:00
* icf + + = cbrt_tab [ n ] | ( bits & 1 < < 31 ) ;
2010-01-13 18:46:28 +02:00
bits < < = 1 ;
} else {
unsigned v = ( ( const uint32_t * ) vq ) [ cb_idx & 15 ] ;
2010-01-13 18:46:32 +02:00
* icf + + = ( bits & 1 < < 31 ) | v ;
2010-01-13 18:46:28 +02:00
bits < < = ! ! v ;
2009-02-26 03:54:16 +02:00
}
2010-01-13 18:46:28 +02:00
cb_idx > > = 4 ;
2008-08-15 11:01:31 +03:00
}
2010-01-13 18:46:32 +02:00
} while ( len - = 2 ) ;
2009-09-22 03:48:45 +03:00
2010-01-13 18:46:32 +02:00
ac - > dsp . vector_fmul_scalar ( cfo , cfo , sf [ idx ] , off_len ) ;
2009-09-22 03:48:45 +03:00
}
2008-08-15 11:01:31 +03:00
}
2010-01-15 16:02:52 +02:00
CLOSE_READER ( re , gb ) ;
2008-08-15 11:01:31 +03:00
}
}
2010-01-13 18:46:32 +02:00
coef + = g_len < < 7 ;
2008-08-15 11:01:31 +03:00
}
if ( pulse_present ) {
2008-09-13 23:51:36 +03:00
idx = 0 ;
2009-08-02 13:50:59 +03:00
for ( i = 0 ; i < pulse - > num_pulse ; i + + ) {
float co = coef_base [ pulse - > pos [ i ] ] ;
while ( offsets [ idx + 1 ] < = pulse - > pos [ i ] )
2008-09-13 23:51:36 +03:00
idx + + ;
if ( band_type [ idx ] ! = NOISE_BT & & sf [ idx ] ) {
2008-09-13 23:52:57 +03:00
float ico = - pulse - > amp [ i ] ;
if ( co ) {
co / = sf [ idx ] ;
ico = co / sqrtf ( sqrtf ( fabsf ( co ) ) ) + ( co > 0 ? - ico : ico ) ;
}
coef_base [ pulse - > pos [ i ] ] = cbrtf ( fabsf ( ico ) ) * ico * sf [ idx ] ;
2008-09-13 23:51:36 +03:00
}
2008-08-15 11:01:31 +03:00
}
}
return 0 ;
2010-01-13 18:46:28 +02:00
err_cb_overflow :
av_log ( ac - > avccontext , AV_LOG_ERROR ,
" Read beyond end of ff_aac_codebook_vectors[%d][]. index %d >= %d \n " ,
band_type [ idx ] , err_idx , ff_aac_spectral_sizes [ band_type [ idx ] ] ) ;
return - 1 ;
2008-08-15 11:01:31 +03:00
}
2009-08-02 13:50:59 +03:00
static av_always_inline float flt16_round ( float pf )
{
2009-03-16 18:11:27 +02:00
union float754 tmp ;
tmp . f = pf ;
tmp . i = ( tmp . i + 0x00008000U ) & 0xFFFF0000U ;
return tmp . f ;
2008-11-24 02:13:50 +02:00
}
2009-08-02 13:50:59 +03:00
static av_always_inline float flt16_even ( float pf )
{
2009-03-16 18:11:27 +02:00
union float754 tmp ;
tmp . f = pf ;
2009-08-02 13:50:59 +03:00
tmp . i = ( tmp . i + 0x00007FFFU + ( tmp . i & 0x00010000U > > 16 ) ) & 0xFFFF0000U ;
2009-03-16 18:11:27 +02:00
return tmp . f ;
2008-11-24 02:13:50 +02:00
}
2009-08-02 13:50:59 +03:00
static av_always_inline float flt16_trunc ( float pf )
{
2009-03-16 18:11:27 +02:00
union float754 pun ;
pun . f = pf ;
pun . i & = 0xFFFF0000U ;
return pun . f ;
2008-11-24 02:13:50 +02:00
}
2009-08-02 13:50:59 +03:00
static void predict ( AACContext * ac , PredictorState * ps , float * coef ,
int output_enable )
{
const float a = 0.953125 ; // 61.0 / 64
const float alpha = 0.90625 ; // 29.0 / 32
2008-11-24 02:13:50 +02:00
float e0 , e1 ;
float pv ;
float k1 , k2 ;
k1 = ps - > var0 > 1 ? ps - > cor0 * flt16_even ( a / ps - > var0 ) : 0 ;
k2 = ps - > var1 > 1 ? ps - > cor1 * flt16_even ( a / ps - > var1 ) : 0 ;
pv = flt16_round ( k1 * ps - > r0 + k2 * ps - > r1 ) ;
if ( output_enable )
* coef + = pv * ac - > sf_scale ;
e0 = * coef / ac - > sf_scale ;
e1 = e0 - k1 * ps - > r0 ;
ps - > cor1 = flt16_trunc ( alpha * ps - > cor1 + ps - > r1 * e1 ) ;
ps - > var1 = flt16_trunc ( alpha * ps - > var1 + 0.5 * ( ps - > r1 * ps - > r1 + e1 * e1 ) ) ;
ps - > cor0 = flt16_trunc ( alpha * ps - > cor0 + ps - > r0 * e0 ) ;
ps - > var0 = flt16_trunc ( alpha * ps - > var0 + 0.5 * ( ps - > r0 * ps - > r0 + e0 * e0 ) ) ;
ps - > r1 = flt16_trunc ( a * ( ps - > r0 - k1 * e0 ) ) ;
ps - > r0 = flt16_trunc ( a * e0 ) ;
}
/**
* Apply AAC - Main style frequency domain prediction .
*/
2009-08-02 13:50:59 +03:00
static void apply_prediction ( AACContext * ac , SingleChannelElement * sce )
{
2008-11-24 02:13:50 +02:00
int sfb , k ;
if ( ! sce - > ics . predictor_initialized ) {
2008-12-21 07:28:14 +02:00
reset_all_predictors ( sce - > predictor_state ) ;
2008-11-24 02:13:50 +02:00
sce - > ics . predictor_initialized = 1 ;
}
if ( sce - > ics . window_sequence [ 0 ] ! = EIGHT_SHORT_SEQUENCE ) {
for ( sfb = 0 ; sfb < ff_aac_pred_sfb_max [ ac - > m4ac . sampling_index ] ; sfb + + ) {
for ( k = sce - > ics . swb_offset [ sfb ] ; k < sce - > ics . swb_offset [ sfb + 1 ] ; k + + ) {
2008-12-21 07:28:14 +02:00
predict ( ac , & sce - > predictor_state [ k ] , & sce - > coeffs [ k ] ,
2009-08-02 13:50:59 +03:00
sce - > ics . predictor_present & & sce - > ics . prediction_used [ sfb ] ) ;
2008-11-24 02:13:50 +02:00
}
}
if ( sce - > ics . predictor_reset_group )
2008-12-21 07:28:14 +02:00
reset_predictor_group ( sce - > predictor_state , sce - > ics . predictor_reset_group ) ;
2008-11-24 02:13:50 +02:00
} else
2008-12-21 07:28:14 +02:00
reset_all_predictors ( sce - > predictor_state ) ;
2008-11-24 02:13:50 +02:00
}
2008-08-09 13:46:27 +03:00
/**
2008-08-11 14:16:06 +03:00
* Decode an individual_channel_stream payload ; reference : table 4.44 .
*
* @ param common_window Channels have independent [ 0 ] , or shared [ 1 ] , Individual Channel Stream information .
* @ param scale_flag scalable [ 1 ] or non - scalable [ 0 ] AAC ( Unused until scalable AAC is implemented . )
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_ics ( AACContext * ac , SingleChannelElement * sce ,
GetBitContext * gb , int common_window , int scale_flag )
{
2008-08-11 14:16:06 +03:00
Pulse pulse ;
2009-08-02 13:50:59 +03:00
TemporalNoiseShaping * tns = & sce - > tns ;
IndividualChannelStream * ics = & sce - > ics ;
float * out = sce - > coeffs ;
2008-08-11 14:16:06 +03:00
int global_gain , pulse_present = 0 ;
2008-08-15 03:19:14 +03:00
/* This assignment is to silence a GCC warning about the variable being used
* uninitialized when in fact it always is .
2008-08-11 14:16:06 +03:00
*/
pulse . num_pulse = 0 ;
global_gain = get_bits ( gb , 8 ) ;
if ( ! common_window & & ! scale_flag ) {
if ( decode_ics_info ( ac , ics , gb , 0 ) < 0 )
return - 1 ;
}
if ( decode_band_types ( ac , sce - > band_type , sce - > band_type_run_end , gb , ics ) < 0 )
return - 1 ;
if ( decode_scalefactors ( ac , sce - > sf , gb , global_gain , ics , sce - > band_type , sce - > band_type_run_end ) < 0 )
return - 1 ;
pulse_present = 0 ;
if ( ! scale_flag ) {
if ( ( pulse_present = get_bits1 ( gb ) ) ) {
if ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " Pulse tool not allowed in eight short sequence. \n " ) ;
return - 1 ;
}
2008-09-16 18:59:43 +03:00
if ( decode_pulses ( & pulse , gb , ics - > swb_offset , ics - > num_swb ) ) {
av_log ( ac - > avccontext , AV_LOG_ERROR , " Pulse data corrupt or invalid. \n " ) ;
return - 1 ;
}
2008-08-11 14:16:06 +03:00
}
if ( ( tns - > present = get_bits1 ( gb ) ) & & decode_tns ( ac , tns , gb , ics ) )
return - 1 ;
if ( get_bits1 ( gb ) ) {
2009-06-29 22:07:04 +03:00
av_log_missing_feature ( ac - > avccontext , " SSR " , 1 ) ;
2008-08-11 14:16:06 +03:00
return - 1 ;
}
}
2008-08-15 03:19:14 +03:00
if ( decode_spectrum_and_dequant ( ac , out , gb , sce - > sf , pulse_present , & pulse , ics , sce - > band_type ) < 0 )
2008-08-11 14:16:06 +03:00
return - 1 ;
2008-11-24 02:13:50 +02:00
2009-08-02 13:50:59 +03:00
if ( ac - > m4ac . object_type = = AOT_AAC_MAIN & & ! common_window )
2008-11-24 02:13:50 +02:00
apply_prediction ( ac , sce ) ;
2008-08-11 14:16:06 +03:00
return 0 ;
}
2008-08-15 11:01:31 +03:00
/**
* Mid / Side stereo decoding ; reference : 4.6 .8 .1 .3 .
*/
2009-09-22 03:48:45 +03:00
static void apply_mid_side_stereo ( AACContext * ac , ChannelElement * cpe )
2009-08-02 13:50:59 +03:00
{
const IndividualChannelStream * ics = & cpe - > ch [ 0 ] . ics ;
2008-08-15 11:01:31 +03:00
float * ch0 = cpe - > ch [ 0 ] . coeffs ;
float * ch1 = cpe - > ch [ 1 ] . coeffs ;
2009-09-22 03:48:45 +03:00
int g , i , group , idx = 0 ;
2009-08-02 13:50:59 +03:00
const uint16_t * offsets = ics - > swb_offset ;
2008-08-15 11:01:31 +03:00
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
for ( i = 0 ; i < ics - > max_sfb ; i + + , idx + + ) {
if ( cpe - > ms_mask [ idx ] & &
2009-08-02 13:50:59 +03:00
cpe - > ch [ 0 ] . band_type [ idx ] < NOISE_BT & & cpe - > ch [ 1 ] . band_type [ idx ] < NOISE_BT ) {
2008-08-15 11:01:31 +03:00
for ( group = 0 ; group < ics - > group_len [ g ] ; group + + ) {
2009-09-22 03:48:45 +03:00
ac - > dsp . butterflies_float ( ch0 + group * 128 + offsets [ i ] ,
ch1 + group * 128 + offsets [ i ] ,
offsets [ i + 1 ] - offsets [ i ] ) ;
2008-08-15 11:01:31 +03:00
}
}
}
2009-08-02 13:50:59 +03:00
ch0 + = ics - > group_len [ g ] * 128 ;
ch1 + = ics - > group_len [ g ] * 128 ;
2008-08-15 11:01:31 +03:00
}
}
/**
* intensity stereo decoding ; reference : 4.6 .8 .2 .3
*
* @ param ms_present Indicates mid / side stereo presence . [ 0 ] mask is all 0 s ;
* [ 1 ] mask is decoded from bitstream ; [ 2 ] mask is all 1 s ;
* [ 3 ] reserved for scalable AAC
*/
2009-08-02 13:50:59 +03:00
static void apply_intensity_stereo ( ChannelElement * cpe , int ms_present )
{
const IndividualChannelStream * ics = & cpe - > ch [ 1 ] . ics ;
SingleChannelElement * sce1 = & cpe - > ch [ 1 ] ;
2008-08-15 11:01:31 +03:00
float * coef0 = cpe - > ch [ 0 ] . coeffs , * coef1 = cpe - > ch [ 1 ] . coeffs ;
2009-08-02 13:50:59 +03:00
const uint16_t * offsets = ics - > swb_offset ;
2008-08-15 11:01:31 +03:00
int g , group , i , k , idx = 0 ;
int c ;
float scale ;
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
for ( i = 0 ; i < ics - > max_sfb ; ) {
if ( sce1 - > band_type [ idx ] = = INTENSITY_BT | | sce1 - > band_type [ idx ] = = INTENSITY_BT2 ) {
const int bt_run_end = sce1 - > band_type_run_end [ idx ] ;
for ( ; i < bt_run_end ; i + + , idx + + ) {
c = - 1 + 2 * ( sce1 - > band_type [ idx ] - 14 ) ;
if ( ms_present )
c * = 1 - 2 * cpe - > ms_mask [ idx ] ;
scale = c * sce1 - > sf [ idx ] ;
for ( group = 0 ; group < ics - > group_len [ g ] ; group + + )
2009-08-02 13:50:59 +03:00
for ( k = offsets [ i ] ; k < offsets [ i + 1 ] ; k + + )
coef1 [ group * 128 + k ] = scale * coef0 [ group * 128 + k ] ;
2008-08-15 11:01:31 +03:00
}
} else {
int bt_run_end = sce1 - > band_type_run_end [ idx ] ;
idx + = bt_run_end - i ;
i = bt_run_end ;
}
}
2009-08-02 13:50:59 +03:00
coef0 + = ics - > group_len [ g ] * 128 ;
coef1 + = ics - > group_len [ g ] * 128 ;
2008-08-15 11:01:31 +03:00
}
}
2008-08-11 14:16:06 +03:00
/**
* Decode a channel_pair_element ; reference : table 4.4 .
*
* @ param elem_id Identifies the instance of a syntax element .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_cpe ( AACContext * ac , GetBitContext * gb , ChannelElement * cpe )
{
2008-08-11 14:16:06 +03:00
int i , ret , common_window , ms_present = 0 ;
common_window = get_bits1 ( gb ) ;
if ( common_window ) {
if ( decode_ics_info ( ac , & cpe - > ch [ 0 ] . ics , gb , 1 ) )
return - 1 ;
i = cpe - > ch [ 1 ] . ics . use_kb_window [ 0 ] ;
cpe - > ch [ 1 ] . ics = cpe - > ch [ 0 ] . ics ;
cpe - > ch [ 1 ] . ics . use_kb_window [ 1 ] = i ;
ms_present = get_bits ( gb , 2 ) ;
2009-08-02 13:50:59 +03:00
if ( ms_present = = 3 ) {
2008-08-11 14:16:06 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " ms_present = 3 is reserved. \n " ) ;
return - 1 ;
2009-08-02 13:50:59 +03:00
} else if ( ms_present )
2008-08-11 14:16:06 +03:00
decode_mid_side_stereo ( cpe , gb , ms_present ) ;
}
if ( ( ret = decode_ics ( ac , & cpe - > ch [ 0 ] , gb , common_window , 0 ) ) )
return ret ;
if ( ( ret = decode_ics ( ac , & cpe - > ch [ 1 ] , gb , common_window , 0 ) ) )
return ret ;
2008-12-21 07:28:14 +02:00
if ( common_window ) {
if ( ms_present )
2009-09-22 03:48:45 +03:00
apply_mid_side_stereo ( ac , cpe ) ;
2008-12-21 07:28:14 +02:00
if ( ac - > m4ac . object_type = = AOT_AAC_MAIN ) {
apply_prediction ( ac , & cpe - > ch [ 0 ] ) ;
apply_prediction ( ac , & cpe - > ch [ 1 ] ) ;
}
}
2008-08-11 14:16:06 +03:00
2008-08-15 03:19:14 +03:00
apply_intensity_stereo ( cpe , ms_present ) ;
2008-08-11 14:16:06 +03:00
return 0 ;
}
2008-08-15 11:01:31 +03:00
/**
* Decode coupling_channel_element ; reference : table 4.8 .
*
* @ param elem_id Identifies the instance of a syntax element .
*
* @ return Returns error status . 0 - OK , ! 0 - error
*/
2009-08-02 13:50:59 +03:00
static int decode_cce ( AACContext * ac , GetBitContext * gb , ChannelElement * che )
{
2008-08-15 11:01:31 +03:00
int num_gain = 0 ;
2008-09-18 19:02:51 +03:00
int c , g , sfb , ret ;
2008-08-15 11:01:31 +03:00
int sign ;
float scale ;
2009-08-02 13:50:59 +03:00
SingleChannelElement * sce = & che - > ch [ 0 ] ;
ChannelCoupling * coup = & che - > coup ;
2008-08-15 11:01:31 +03:00
2009-08-02 13:50:59 +03:00
coup - > coupling_point = 2 * get_bits1 ( gb ) ;
2008-08-15 03:05:09 +03:00
coup - > num_coupled = get_bits ( gb , 3 ) ;
for ( c = 0 ; c < = coup - > num_coupled ; c + + ) {
num_gain + + ;
coup - > type [ c ] = get_bits1 ( gb ) ? TYPE_CPE : TYPE_SCE ;
coup - > id_select [ c ] = get_bits ( gb , 4 ) ;
if ( coup - > type [ c ] = = TYPE_CPE ) {
coup - > ch_select [ c ] = get_bits ( gb , 2 ) ;
if ( coup - > ch_select [ c ] = = 3 )
num_gain + + ;
} else
2008-10-06 19:12:30 +03:00
coup - > ch_select [ c ] = 2 ;
2008-08-15 03:05:09 +03:00
}
2009-08-02 13:50:59 +03:00
coup - > coupling_point + = get_bits1 ( gb ) | | ( coup - > coupling_point > > 1 ) ;
2008-08-15 03:05:09 +03:00
2009-08-02 13:50:59 +03:00
sign = get_bits ( gb , 1 ) ;
2008-09-18 18:35:08 +03:00
scale = pow ( 2. , pow ( 2. , ( int ) get_bits ( gb , 2 ) - 3 ) ) ;
2008-08-15 03:05:09 +03:00
if ( ( ret = decode_ics ( ac , sce , gb , 0 , 0 ) ) )
return ret ;
for ( c = 0 ; c < num_gain ; c + + ) {
2009-08-02 13:50:59 +03:00
int idx = 0 ;
int cge = 1 ;
2008-08-15 03:05:09 +03:00
int gain = 0 ;
float gain_cache = 1. ;
if ( c ) {
cge = coup - > coupling_point = = AFTER_IMDCT ? 1 : get_bits1 ( gb ) ;
gain = cge ? get_vlc2 ( gb , vlc_scalefactors . table , 7 , 3 ) - 60 : 0 ;
2008-10-06 19:12:30 +03:00
gain_cache = pow ( scale , - gain ) ;
2008-08-15 03:05:09 +03:00
}
2009-02-13 18:06:22 +02:00
if ( coup - > coupling_point = = AFTER_IMDCT ) {
coup - > gain [ c ] [ 0 ] = gain_cache ;
} else {
2009-02-13 18:07:20 +02:00
for ( g = 0 ; g < sce - > ics . num_window_groups ; g + + ) {
for ( sfb = 0 ; sfb < sce - > ics . max_sfb ; sfb + + , idx + + ) {
if ( sce - > band_type [ idx ] ! = ZERO_BT ) {
if ( ! cge ) {
int t = get_vlc2 ( gb , vlc_scalefactors . table , 7 , 3 ) - 60 ;
2009-08-02 13:50:59 +03:00
if ( t ) {
2009-02-13 18:07:20 +02:00
int s = 1 ;
t = gain + = t ;
if ( sign ) {
s - = 2 * ( t & 0x1 ) ;
t > > = 1 ;
}
gain_cache = pow ( scale , - t ) * s ;
2008-08-15 03:05:09 +03:00
}
}
2009-02-13 18:07:20 +02:00
coup - > gain [ c ] [ idx ] = gain_cache ;
2008-08-15 03:05:09 +03:00
}
}
2008-09-18 18:48:37 +03:00
}
}
2008-08-15 03:05:09 +03:00
}
return 0 ;
}
2008-08-11 14:16:06 +03:00
/**
* Decode Spectral Band Replication extension data ; reference : table 4.55 .
2008-08-09 13:46:27 +03:00
*
* @ param crc flag indicating the presence of CRC checksum
* @ param cnt length of TYPE_FIL syntactic element in bytes
2008-08-11 14:16:06 +03:00
*
2008-08-09 13:46:27 +03:00
* @ return Returns number of bytes consumed from the TYPE_FIL element .
*/
2009-08-02 13:50:59 +03:00
static int decode_sbr_extension ( AACContext * ac , GetBitContext * gb ,
int crc , int cnt )
{
2008-08-09 13:46:27 +03:00
// TODO : sbr_extension implementation
2009-06-29 22:07:04 +03:00
av_log_missing_feature ( ac - > avccontext , " SBR " , 0 ) ;
2009-08-02 13:50:59 +03:00
skip_bits_long ( gb , 8 * cnt - 4 ) ; // -4 due to reading extension type
2008-08-09 13:46:27 +03:00
return cnt ;
}
2008-08-15 03:05:09 +03:00
/**
* Parse whether channels are to be excluded from Dynamic Range Compression ; reference : table 4.53 .
*
* @ return Returns number of bytes consumed .
*/
2009-08-02 13:50:59 +03:00
static int decode_drc_channel_exclusions ( DynamicRangeControl * che_drc ,
GetBitContext * gb )
{
2008-08-15 03:05:09 +03:00
int i ;
int num_excl_chan = 0 ;
do {
for ( i = 0 ; i < 7 ; i + + )
che_drc - > exclude_mask [ num_excl_chan + + ] = get_bits1 ( gb ) ;
} while ( num_excl_chan < MAX_CHANNELS - 7 & & get_bits1 ( gb ) ) ;
return num_excl_chan / 7 ;
}
2008-08-11 14:16:06 +03:00
/**
* Decode dynamic range information ; reference : table 4.52 .
*
* @ param cnt length of TYPE_FIL syntactic element in bytes
*
* @ return Returns number of bytes consumed .
*/
2009-08-02 13:50:59 +03:00
static int decode_dynamic_range ( DynamicRangeControl * che_drc ,
GetBitContext * gb , int cnt )
{
int n = 1 ;
2008-08-11 14:16:06 +03:00
int drc_num_bands = 1 ;
int i ;
/* pce_tag_present? */
2009-08-02 13:50:59 +03:00
if ( get_bits1 ( gb ) ) {
2008-08-11 14:16:06 +03:00
che_drc - > pce_instance_tag = get_bits ( gb , 4 ) ;
skip_bits ( gb , 4 ) ; // tag_reserved_bits
n + + ;
}
/* excluded_chns_present? */
2009-08-02 13:50:59 +03:00
if ( get_bits1 ( gb ) ) {
2008-08-11 14:16:06 +03:00
n + = decode_drc_channel_exclusions ( che_drc , gb ) ;
}
/* drc_bands_present? */
if ( get_bits1 ( gb ) ) {
che_drc - > band_incr = get_bits ( gb , 4 ) ;
che_drc - > interpolation_scheme = get_bits ( gb , 4 ) ;
n + + ;
drc_num_bands + = che_drc - > band_incr ;
for ( i = 0 ; i < drc_num_bands ; i + + ) {
che_drc - > band_top [ i ] = get_bits ( gb , 8 ) ;
n + + ;
}
}
/* prog_ref_level_present? */
if ( get_bits1 ( gb ) ) {
che_drc - > prog_ref_level = get_bits ( gb , 7 ) ;
skip_bits1 ( gb ) ; // prog_ref_level_reserved_bits
n + + ;
}
for ( i = 0 ; i < drc_num_bands ; i + + ) {
che_drc - > dyn_rng_sgn [ i ] = get_bits1 ( gb ) ;
che_drc - > dyn_rng_ctl [ i ] = get_bits ( gb , 7 ) ;
n + + ;
}
return n ;
}
/**
* Decode extension data ( incomplete ) ; reference : table 4.51 .
*
* @ param cnt length of TYPE_FIL syntactic element in bytes
*
* @ return Returns number of bytes consumed
*/
2009-08-02 13:50:59 +03:00
static int decode_extension_payload ( AACContext * ac , GetBitContext * gb , int cnt )
{
2008-08-09 13:46:27 +03:00
int crc_flag = 0 ;
int res = cnt ;
switch ( get_bits ( gb , 4 ) ) { // extension type
2009-08-02 13:50:59 +03:00
case EXT_SBR_DATA_CRC :
crc_flag + + ;
case EXT_SBR_DATA :
res = decode_sbr_extension ( ac , gb , crc_flag , cnt ) ;
break ;
case EXT_DYNAMIC_RANGE :
res = decode_dynamic_range ( & ac - > che_drc , gb , cnt ) ;
break ;
case EXT_FILL :
case EXT_FILL_DATA :
case EXT_DATA_ELEMENT :
default :
skip_bits_long ( gb , 8 * cnt - 4 ) ;
break ;
2008-08-09 13:46:27 +03:00
} ;
return res ;
}
2008-08-21 10:21:26 +03:00
/**
* Decode Temporal Noise Shaping filter coefficients and apply all - pole filters ; reference : 4.6 .9 .3 .
*
* @ param decode 1 if tool is used normally , 0 if tool is used in LTP .
* @ param coef spectral coefficients
*/
2009-08-02 13:50:59 +03:00
static void apply_tns ( float coef [ 1024 ] , TemporalNoiseShaping * tns ,
IndividualChannelStream * ics , int decode )
{
const int mmm = FFMIN ( ics - > tns_max_bands , ics - > max_sfb ) ;
2008-08-21 14:29:28 +03:00
int w , filt , m , i ;
2008-08-21 10:21:26 +03:00
int bottom , top , order , start , end , size , inc ;
float lpc [ TNS_MAX_ORDER ] ;
for ( w = 0 ; w < ics - > num_windows ; w + + ) {
bottom = ics - > num_swb ;
for ( filt = 0 ; filt < tns - > n_filt [ w ] ; filt + + ) {
top = bottom ;
bottom = FFMAX ( 0 , top - tns - > length [ w ] [ filt ] ) ;
order = tns - > order [ w ] [ filt ] ;
if ( order = = 0 )
continue ;
2008-09-04 14:03:14 +03:00
// tns_decode_coef
compute_lpc_coefs ( tns - > coef [ w ] [ filt ] , order , lpc , 0 , 0 , 0 ) ;
2008-08-21 10:21:26 +03:00
2008-08-19 00:36:58 +03:00
start = ics - > swb_offset [ FFMIN ( bottom , mmm ) ] ;
end = ics - > swb_offset [ FFMIN ( top , mmm ) ] ;
if ( ( size = end - start ) < = 0 )
continue ;
if ( tns - > direction [ w ] [ filt ] ) {
2009-08-02 13:50:59 +03:00
inc = - 1 ;
start = end - 1 ;
2008-08-19 00:36:58 +03:00
} else {
inc = 1 ;
}
start + = w * 128 ;
// ar filter
for ( m = 0 ; m < size ; m + + , start + = inc )
for ( i = 1 ; i < = FFMIN ( m , order ) ; i + + )
2009-08-02 13:50:59 +03:00
coef [ start ] - = coef [ start - i * inc ] * lpc [ i - 1 ] ;
2008-08-19 00:36:58 +03:00
}
}
}
2008-08-11 14:16:06 +03:00
/**
* Conduct IMDCT and windowing .
*/
2009-08-02 13:50:59 +03:00
static void imdct_and_windowing ( AACContext * ac , SingleChannelElement * sce )
{
IndividualChannelStream * ics = & sce - > ics ;
float * in = sce - > coeffs ;
float * out = sce - > ret ;
float * saved = sce - > saved ;
const float * swindow = ics - > use_kb_window [ 0 ] ? ff_aac_kbd_short_128 : ff_sine_128 ;
const float * lwindow_prev = ics - > use_kb_window [ 1 ] ? ff_aac_kbd_long_1024 : ff_sine_1024 ;
const float * swindow_prev = ics - > use_kb_window [ 1 ] ? ff_aac_kbd_short_128 : ff_sine_128 ;
float * buf = ac - > buf_mdct ;
float * temp = ac - > temp ;
2008-08-11 14:16:06 +03:00
int i ;
2008-08-22 21:18:50 +03:00
// imdct
2008-08-15 03:05:09 +03:00
if ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) {
if ( ics - > window_sequence [ 1 ] = = ONLY_LONG_SEQUENCE | | ics - > window_sequence [ 1 ] = = LONG_STOP_SEQUENCE )
av_log ( ac - > avccontext , AV_LOG_WARNING ,
" Transition from an ONLY_LONG or LONG_STOP to an EIGHT_SHORT sequence detected. "
" If you heard an audible artifact, please submit the sample to the FFmpeg developers. \n " ) ;
2008-08-22 21:21:22 +03:00
for ( i = 0 ; i < 1024 ; i + = 128 )
ff_imdct_half ( & ac - > mdct_small , buf + i , in + i ) ;
2008-08-22 21:18:50 +03:00
} else
2008-08-22 21:21:22 +03:00
ff_imdct_half ( & ac - > mdct , buf , in ) ;
2008-08-22 21:18:50 +03:00
/* window overlapping
* NOTE : To simplify the overlapping code , all ' meaningless ' short to long
* and long to short transitions are considered to be short to short
* transitions . This leaves just two cases ( long to long and short to short )
* with a little special sauce for EIGHT_SHORT_SEQUENCE .
*/
if ( ( ics - > window_sequence [ 1 ] = = ONLY_LONG_SEQUENCE | | ics - > window_sequence [ 1 ] = = LONG_STOP_SEQUENCE ) & &
2009-08-02 13:50:59 +03:00
( ics - > window_sequence [ 0 ] = = ONLY_LONG_SEQUENCE | | ics - > window_sequence [ 0 ] = = LONG_START_SEQUENCE ) ) {
2008-08-22 21:21:22 +03:00
ac - > dsp . vector_fmul_window ( out , saved , buf , lwindow_prev , ac - > add_bias , 512 ) ;
2008-08-22 21:18:50 +03:00
} else {
2008-08-22 21:19:18 +03:00
for ( i = 0 ; i < 448 ; i + + )
out [ i ] = saved [ i ] + ac - > add_bias ;
2008-08-15 03:05:09 +03:00
2008-08-22 21:18:50 +03:00
if ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) {
2008-08-22 21:21:22 +03:00
ac - > dsp . vector_fmul_window ( out + 448 + 0 * 128 , saved + 448 , buf + 0 * 128 , swindow_prev , ac - > add_bias , 64 ) ;
ac - > dsp . vector_fmul_window ( out + 448 + 1 * 128 , buf + 0 * 128 + 64 , buf + 1 * 128 , swindow , ac - > add_bias , 64 ) ;
ac - > dsp . vector_fmul_window ( out + 448 + 2 * 128 , buf + 1 * 128 + 64 , buf + 2 * 128 , swindow , ac - > add_bias , 64 ) ;
ac - > dsp . vector_fmul_window ( out + 448 + 3 * 128 , buf + 2 * 128 + 64 , buf + 3 * 128 , swindow , ac - > add_bias , 64 ) ;
ac - > dsp . vector_fmul_window ( temp , buf + 3 * 128 + 64 , buf + 4 * 128 , swindow , ac - > add_bias , 64 ) ;
memcpy ( out + 448 + 4 * 128 , temp , 64 * sizeof ( float ) ) ;
2008-08-22 21:18:50 +03:00
} else {
2008-08-22 21:21:22 +03:00
ac - > dsp . vector_fmul_window ( out + 448 , saved + 448 , buf , swindow_prev , ac - > add_bias , 64 ) ;
2008-08-22 21:19:18 +03:00
for ( i = 576 ; i < 1024 ; i + + )
2008-08-22 21:21:22 +03:00
out [ i ] = buf [ i - 512 ] + ac - > add_bias ;
2008-08-22 21:18:50 +03:00
}
}
2008-08-15 03:05:09 +03:00
2008-08-22 21:18:50 +03:00
// buffer update
if ( ics - > window_sequence [ 0 ] = = EIGHT_SHORT_SEQUENCE ) {
2008-08-22 21:21:22 +03:00
for ( i = 0 ; i < 64 ; i + + )
saved [ i ] = temp [ 64 + i ] - ac - > add_bias ;
ac - > dsp . vector_fmul_window ( saved + 64 , buf + 4 * 128 + 64 , buf + 5 * 128 , swindow , 0 , 64 ) ;
ac - > dsp . vector_fmul_window ( saved + 192 , buf + 5 * 128 + 64 , buf + 6 * 128 , swindow , 0 , 64 ) ;
ac - > dsp . vector_fmul_window ( saved + 320 , buf + 6 * 128 + 64 , buf + 7 * 128 , swindow , 0 , 64 ) ;
memcpy ( saved + 448 , buf + 7 * 128 + 64 , 64 * sizeof ( float ) ) ;
2008-08-22 21:18:50 +03:00
} else if ( ics - > window_sequence [ 0 ] = = LONG_START_SEQUENCE ) {
2008-08-22 21:21:22 +03:00
memcpy ( saved , buf + 512 , 448 * sizeof ( float ) ) ;
memcpy ( saved + 448 , buf + 7 * 128 + 64 , 64 * sizeof ( float ) ) ;
2008-08-22 21:18:50 +03:00
} else { // LONG_STOP or ONLY_LONG
2008-08-22 21:21:22 +03:00
memcpy ( saved , buf + 512 , 512 * sizeof ( float ) ) ;
2008-08-15 03:05:09 +03:00
}
}
2008-08-09 13:46:27 +03:00
/**
* Apply dependent channel coupling ( applied before IMDCT ) .
*
* @ param index index into coupling gain array
*/
2009-08-02 13:50:59 +03:00
static void apply_dependent_coupling ( AACContext * ac ,
SingleChannelElement * target ,
ChannelElement * cce , int index )
{
IndividualChannelStream * ics = & cce - > ch [ 0 ] . ics ;
const uint16_t * offsets = ics - > swb_offset ;
float * dest = target - > coeffs ;
const float * src = cce - > ch [ 0 ] . coeffs ;
2008-08-09 13:46:27 +03:00
int g , i , group , k , idx = 0 ;
2009-08-02 13:50:59 +03:00
if ( ac - > m4ac . object_type = = AOT_AAC_LTP ) {
2008-08-09 13:46:27 +03:00
av_log ( ac - > avccontext , AV_LOG_ERROR ,
" Dependent coupling is not supported together with LTP \n " ) ;
return ;
}
for ( g = 0 ; g < ics - > num_window_groups ; g + + ) {
for ( i = 0 ; i < ics - > max_sfb ; i + + , idx + + ) {
2008-10-06 19:22:11 +03:00
if ( cce - > ch [ 0 ] . band_type [ idx ] ! = ZERO_BT ) {
2009-03-06 01:10:22 +02:00
const float gain = cce - > coup . gain [ index ] [ idx ] ;
2008-08-09 13:46:27 +03:00
for ( group = 0 ; group < ics - > group_len [ g ] ; group + + ) {
2009-08-02 13:50:59 +03:00
for ( k = offsets [ i ] ; k < offsets [ i + 1 ] ; k + + ) {
2008-08-09 13:46:27 +03:00
// XXX dsputil-ize
2009-08-02 13:50:59 +03:00
dest [ group * 128 + k ] + = gain * src [ group * 128 + k ] ;
2008-08-09 13:46:27 +03:00
}
}
}
}
2009-08-02 13:50:59 +03:00
dest + = ics - > group_len [ g ] * 128 ;
src + = ics - > group_len [ g ] * 128 ;
2008-08-09 13:46:27 +03:00
}
}
/**
* Apply independent channel coupling ( applied after IMDCT ) .
*
* @ param index index into coupling gain array
*/
2009-08-02 13:50:59 +03:00
static void apply_independent_coupling ( AACContext * ac ,
SingleChannelElement * target ,
ChannelElement * cce , int index )
{
2008-08-09 13:46:27 +03:00
int i ;
2009-02-26 03:50:00 +02:00
const float gain = cce - > coup . gain [ index ] [ 0 ] ;
const float bias = ac - > add_bias ;
2009-08-02 13:50:59 +03:00
const float * src = cce - > ch [ 0 ] . ret ;
float * dest = target - > ret ;
2009-02-26 03:50:00 +02:00
2008-08-09 13:46:27 +03:00
for ( i = 0 ; i < 1024 ; i + + )
2009-02-26 03:50:00 +02:00
dest [ i ] + = gain * ( src [ i ] - bias ) ;
2008-08-09 13:46:27 +03:00
}
2008-08-15 11:01:31 +03:00
/**
* channel coupling transformation interface
*
* @ param index index into coupling gain array
* @ param apply_coupling_method pointer to ( in ) dependent coupling function
*/
2009-08-02 13:50:59 +03:00
static void apply_channel_coupling ( AACContext * ac , ChannelElement * cc ,
enum RawDataBlockType type , int elem_id ,
enum CouplingPoint coupling_point ,
void ( * apply_coupling_method ) ( AACContext * ac , SingleChannelElement * target , ChannelElement * cce , int index ) )
2008-08-15 11:01:31 +03:00
{
2008-10-06 19:12:30 +03:00
int i , c ;
for ( i = 0 ; i < MAX_ELEM_ID ; i + + ) {
ChannelElement * cce = ac - > che [ TYPE_CCE ] [ i ] ;
int index = 0 ;
if ( cce & & cce - > coup . coupling_point = = coupling_point ) {
2009-08-02 13:50:59 +03:00
ChannelCoupling * coup = & cce - > coup ;
2008-10-06 19:12:30 +03:00
for ( c = 0 ; c < = coup - > num_coupled ; c + + ) {
if ( coup - > type [ c ] = = type & & coup - > id_select [ c ] = = elem_id ) {
if ( coup - > ch_select [ c ] ! = 1 ) {
apply_coupling_method ( ac , & cc - > ch [ 0 ] , cce , index ) ;
if ( coup - > ch_select [ c ] ! = 0 )
index + + ;
}
if ( coup - > ch_select [ c ] ! = 2 )
apply_coupling_method ( ac , & cc - > ch [ 1 ] , cce , index + + ) ;
} else
index + = 1 + ( coup - > ch_select [ c ] = = 3 ) ;
2008-08-15 11:01:31 +03:00
}
}
}
}
/**
* Convert spectral data to float samples , applying all supported tools as appropriate .
*/
2009-08-02 13:50:59 +03:00
static void spectral_to_sample ( AACContext * ac )
{
2009-12-16 13:39:14 +02:00
int i , type ;
for ( type = 3 ; type > = 0 ; type - - ) {
2008-10-06 19:12:30 +03:00
for ( i = 0 ; i < MAX_ELEM_ID ; i + + ) {
2008-08-15 11:01:31 +03:00
ChannelElement * che = ac - > che [ type ] [ i ] ;
2009-08-02 13:50:59 +03:00
if ( che ) {
if ( type < = TYPE_CPE )
2008-10-06 19:12:30 +03:00
apply_channel_coupling ( ac , che , type , i , BEFORE_TNS , apply_dependent_coupling ) ;
2009-08-02 13:50:59 +03:00
if ( che - > ch [ 0 ] . tns . present )
2008-08-15 11:01:31 +03:00
apply_tns ( che - > ch [ 0 ] . coeffs , & che - > ch [ 0 ] . tns , & che - > ch [ 0 ] . ics , 1 ) ;
2009-08-02 13:50:59 +03:00
if ( che - > ch [ 1 ] . tns . present )
2008-08-15 11:01:31 +03:00
apply_tns ( che - > ch [ 1 ] . coeffs , & che - > ch [ 1 ] . tns , & che - > ch [ 1 ] . ics , 1 ) ;
2009-08-02 13:50:59 +03:00
if ( type < = TYPE_CPE )
2008-10-06 19:12:30 +03:00
apply_channel_coupling ( ac , che , type , i , BETWEEN_TNS_AND_IMDCT , apply_dependent_coupling ) ;
2009-08-02 13:50:59 +03:00
if ( type ! = TYPE_CCE | | che - > coup . coupling_point = = AFTER_IMDCT )
2008-10-06 19:12:30 +03:00
imdct_and_windowing ( ac , & che - > ch [ 0 ] ) ;
2009-08-02 13:50:59 +03:00
if ( type = = TYPE_CPE )
2008-08-15 11:01:31 +03:00
imdct_and_windowing ( ac , & che - > ch [ 1 ] ) ;
2009-08-02 13:50:59 +03:00
if ( type < = TYPE_CCE )
2008-10-06 19:12:30 +03:00
apply_channel_coupling ( ac , che , type , i , AFTER_IMDCT , apply_independent_coupling ) ;
2008-08-15 03:05:09 +03:00
}
}
}
}
2009-08-02 13:50:59 +03:00
static int parse_adts_frame_header ( AACContext * ac , GetBitContext * gb )
{
2009-01-08 00:09:21 +02:00
int size ;
AACADTSHeaderInfo hdr_info ;
size = ff_aac_parse_header ( gb , & hdr_info ) ;
if ( size > 0 ) {
2009-11-04 00:50:02 +02:00
if ( ac - > output_configured ! = OC_LOCKED & & hdr_info . chan_config ) {
2009-07-11 00:53:04 +03:00
enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ;
memset ( new_che_pos , 0 , 4 * MAX_ELEM_ID * sizeof ( new_che_pos [ 0 ] [ 0 ] ) ) ;
2009-01-08 00:09:21 +02:00
ac - > m4ac . chan_config = hdr_info . chan_config ;
2009-07-11 00:53:04 +03:00
if ( set_default_channel_config ( ac , new_che_pos , hdr_info . chan_config ) )
return - 7 ;
2009-11-04 00:50:02 +02:00
if ( output_configure ( ac , ac - > che_pos , new_che_pos , hdr_info . chan_config , OC_TRIAL_FRAME ) )
2009-07-11 00:53:04 +03:00
return - 7 ;
2009-11-04 00:50:02 +02:00
} else if ( ac - > output_configured ! = OC_LOCKED ) {
ac - > output_configured = OC_NONE ;
2009-07-11 00:53:04 +03:00
}
2009-12-02 11:07:32 +02:00
if ( ac - > output_configured ! = OC_LOCKED )
ac - > m4ac . sbr = - 1 ;
2009-01-08 00:09:21 +02:00
ac - > m4ac . sample_rate = hdr_info . sample_rate ;
ac - > m4ac . sampling_index = hdr_info . sampling_index ;
ac - > m4ac . object_type = hdr_info . object_type ;
2009-12-08 21:20:36 +02:00
if ( ! ac - > avccontext - > sample_rate )
ac - > avccontext - > sample_rate = hdr_info . sample_rate ;
2009-03-07 00:37:21 +02:00
if ( hdr_info . num_aac_frames = = 1 ) {
if ( ! hdr_info . crc_absent )
skip_bits ( gb , 16 ) ;
} else {
2009-06-29 22:07:04 +03:00
av_log_missing_feature ( ac - > avccontext , " More than one AAC RDB per ADTS frame is " , 0 ) ;
2009-03-07 00:37:21 +02:00
return - 1 ;
}
2009-03-07 00:36:24 +02:00
}
2009-01-08 00:09:21 +02:00
return size ;
}
2009-08-02 13:50:59 +03:00
static int aac_decode_frame ( AVCodecContext * avccontext , void * data ,
int * data_size , AVPacket * avpkt )
{
2009-04-07 18:59:50 +03:00
const uint8_t * buf = avpkt - > data ;
int buf_size = avpkt - > size ;
2009-08-02 13:50:59 +03:00
AACContext * ac = avccontext - > priv_data ;
ChannelElement * che = NULL ;
2008-08-15 03:05:09 +03:00
GetBitContext gb ;
enum RawDataBlockType elem_type ;
int err , elem_id , data_size_tmp ;
2009-08-02 13:50:59 +03:00
init_get_bits ( & gb , buf , buf_size * 8 ) ;
2008-08-15 03:05:09 +03:00
2009-01-08 00:09:21 +02:00
if ( show_bits ( & gb , 12 ) = = 0xfff ) {
2009-04-19 03:55:46 +03:00
if ( parse_adts_frame_header ( ac , & gb ) < 0 ) {
2009-01-08 00:09:21 +02:00
av_log ( avccontext , AV_LOG_ERROR , " Error decoding AAC frame header. \n " ) ;
return - 1 ;
}
2009-02-12 15:31:43 +02:00
if ( ac - > m4ac . sampling_index > 12 ) {
2009-02-10 15:47:50 +02:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " invalid sampling rate index %d \n " , ac - > m4ac . sampling_index ) ;
return - 1 ;
}
2009-01-08 00:09:21 +02:00
}
2008-08-15 03:05:09 +03:00
// parse
while ( ( elem_type = get_bits ( & gb , 3 ) ) ! = TYPE_END ) {
elem_id = get_bits ( & gb , 4 ) ;
2009-08-02 13:50:59 +03:00
if ( elem_type < TYPE_DSE & & ! ( che = get_che ( ac , elem_type , elem_id ) ) ) {
2009-02-12 15:49:59 +02:00
av_log ( ac - > avccontext , AV_LOG_ERROR , " channel element %d.%d is not allocated \n " , elem_type , elem_id ) ;
return - 1 ;
2008-08-15 03:05:09 +03:00
}
switch ( elem_type ) {
case TYPE_SCE :
2009-03-06 21:47:01 +02:00
err = decode_ics ( ac , & che - > ch [ 0 ] , & gb , 0 , 0 ) ;
2008-08-15 03:05:09 +03:00
break ;
case TYPE_CPE :
2009-03-06 21:47:01 +02:00
err = decode_cpe ( ac , & gb , che ) ;
2008-08-15 03:05:09 +03:00
break ;
case TYPE_CCE :
2009-03-06 21:47:01 +02:00
err = decode_cce ( ac , & gb , che ) ;
2008-08-15 03:05:09 +03:00
break ;
case TYPE_LFE :
2009-03-06 21:47:01 +02:00
err = decode_ics ( ac , & che - > ch [ 0 ] , & gb , 0 , 0 ) ;
2008-08-15 03:05:09 +03:00
break ;
case TYPE_DSE :
skip_data_stream_element ( & gb ) ;
err = 0 ;
break ;
2009-08-02 13:50:59 +03:00
case TYPE_PCE : {
2008-08-15 03:05:09 +03:00
enum ChannelPosition new_che_pos [ 4 ] [ MAX_ELEM_ID ] ;
memset ( new_che_pos , 0 , 4 * MAX_ELEM_ID * sizeof ( new_che_pos [ 0 ] [ 0 ] ) ) ;
2009-08-02 13:50:59 +03:00
if ( ( err = decode_pce ( ac , new_che_pos , & gb ) ) )
2008-08-15 03:05:09 +03:00
break ;
2009-11-21 22:56:46 +02:00
if ( ac - > output_configured > OC_TRIAL_PCE )
2009-07-11 00:53:04 +03:00
av_log ( avccontext , AV_LOG_ERROR ,
" Not evaluating a further program_config_element as this construct is dubious at best. \n " ) ;
else
2009-11-04 00:50:02 +02:00
err = output_configure ( ac , ac - > che_pos , new_che_pos , 0 , OC_TRIAL_PCE ) ;
2008-08-15 03:05:09 +03:00
break ;
}
case TYPE_FIL :
if ( elem_id = = 15 )
elem_id + = get_bits ( & gb , 8 ) - 1 ;
while ( elem_id > 0 )
elem_id - = decode_extension_payload ( ac , & gb , elem_id ) ;
err = 0 ; /* FIXME */
break ;
default :
err = - 1 ; /* should not happen, but keeps compiler happy */
break ;
}
2009-08-02 13:50:59 +03:00
if ( err )
2008-08-15 03:05:09 +03:00
return err ;
}
spectral_to_sample ( ac ) ;
2008-08-11 14:16:06 +03:00
if ( ! ac - > is_saved ) {
ac - > is_saved = 1 ;
* data_size = 0 ;
2008-08-15 03:19:14 +03:00
return buf_size ;
2008-08-11 14:16:06 +03:00
}
data_size_tmp = 1024 * avccontext - > channels * sizeof ( int16_t ) ;
2009-08-02 13:50:59 +03:00
if ( * data_size < data_size_tmp ) {
2008-08-11 14:16:06 +03:00
av_log ( avccontext , AV_LOG_ERROR ,
" Output buffer too small (%d) or trying to output too many samples (%d) for this frame. \n " ,
* data_size , data_size_tmp ) ;
return - 1 ;
}
* data_size = data_size_tmp ;
ac - > dsp . float_to_int16_interleave ( data , ( const float * * ) ac - > output_data , 1024 , avccontext - > channels ) ;
2009-11-04 00:50:02 +02:00
if ( ac - > output_configured )
ac - > output_configured = OC_LOCKED ;
2008-08-11 14:16:06 +03:00
return buf_size ;
}
2009-08-02 13:50:59 +03:00
static av_cold int aac_decode_close ( AVCodecContext * avccontext )
{
AACContext * ac = avccontext - > priv_data ;
2008-08-11 14:22:48 +03:00
int i , type ;
2008-08-05 22:32:01 +03:00
2008-08-09 13:46:27 +03:00
for ( i = 0 ; i < MAX_ELEM_ID ; i + + ) {
2009-08-02 13:50:59 +03:00
for ( type = 0 ; type < 4 ; type + + )
2008-08-11 14:22:48 +03:00
av_freep ( & ac - > che [ type ] [ i ] ) ;
2008-08-05 22:32:01 +03:00
}
ff_mdct_end ( & ac - > mdct ) ;
ff_mdct_end ( & ac - > mdct_small ) ;
2009-08-02 13:50:59 +03:00
return 0 ;
2008-08-05 22:32:01 +03:00
}
AVCodec aac_decoder = {
" aac " ,
CODEC_TYPE_AUDIO ,
CODEC_ID_AAC ,
sizeof ( AACContext ) ,
aac_decode_init ,
NULL ,
aac_decode_close ,
aac_decode_frame ,
. long_name = NULL_IF_CONFIG_SMALL ( " Advanced Audio Coding " ) ,
2009-09-06 12:15:07 +03:00
. sample_fmts = ( const enum SampleFormat [ ] ) {
2009-08-02 13:50:59 +03:00
SAMPLE_FMT_S16 , SAMPLE_FMT_NONE
} ,
2009-09-28 18:35:13 +03:00
. channel_layouts = aac_channel_layout ,
2008-08-05 22:32:01 +03:00
} ;