@ -46,6 +46,44 @@
# include "psymodel.h"
struct AACProfileOptions {
int profile ;
struct AACEncOptions opts ;
} ;
/**
* List of currently supported profiles , anything not listed isn ' t supported .
*/
static const struct AACProfileOptions aacenc_profiles [ ] = {
{ FF_PROFILE_AAC_MAIN ,
{ /* Main profile, all advanced encoding abilities enabled */
. mid_side = 0 ,
. pns = 1 ,
. tns = 0 ,
. pred = OPT_REQUIRED ,
. intensity_stereo = 1 ,
} ,
} ,
{ FF_PROFILE_AAC_LOW ,
{ /* Default profile, these are the settings that get set by default */
. mid_side = 0 ,
. pns = 1 ,
. tns = 0 ,
. pred = OPT_NEEDS_MAIN ,
. intensity_stereo = 1 ,
} ,
} ,
{ FF_PROFILE_MPEG2_AAC_LOW ,
{ /* Strict MPEG 2 Part 7 compliance profile */
. mid_side = 0 ,
. pns = OPT_BANNED ,
. tns = 0 ,
. pred = OPT_BANNED ,
. intensity_stereo = 1 ,
} ,
} ,
} ;
/**
* Make AAC audio config object .
* @ see 1.6 .2 .1 " Syntax - AudioSpecificConfig "
@ -690,8 +728,8 @@ static int aac_encode_frame(AVCodecContext *avctx, AVPacket *avpkt,
}
s - > cur_channel = start_ch ;
}
if ( s - > options . stereo_mo de) { /* Mid/Side stereo */
if ( s - > options . stereo_mo de = = - 1 & & s - > coder - > search_for_ms )
if ( s - > options . mid_si de) { /* Mid/Side stereo */
if ( s - > options . mid_si de = = - 1 & & s - > coder - > search_for_ms )
s - > coder - > search_for_ms ( s , cpe ) ;
else if ( cpe - > common_window )
memset ( cpe - > ms_mask , 1 , sizeof ( cpe - > ms_mask ) ) ;
@ -852,82 +890,88 @@ alloc_fail:
static av_cold int aac_encode_init ( AVCodecContext * avctx )
{
AACEncContext * s = avctx - > priv_data ;
const AACEncOptions * p_opt = NULL ;
int i , ret = 0 ;
const uint8_t * sizes [ 2 ] ;
uint8_t grouping [ AAC_MAX_CHANNELS ] ;
int lengths [ 2 ] ;
s - > channels = avctx - > channels ;
s - > chan_map = aac_chan_configs [ s - > channels - 1 ] ;
s - > random_state = 0x1f2e3d4c ;
s - > lambda = avctx - > global_quality > 0 ? avctx - > global_quality : 120 ;
avctx - > extradata_size = 5 ;
avctx - > frame_size = 1024 ;
avctx - > initial_padding = 1024 ;
avctx - > bit_rate = ( int ) FFMIN (
6144 * s - > channels / 1024.0 * avctx - > sample_rate ,
avctx - > bit_rate ) ;
avctx - > profile = avctx - > profile = = FF_PROFILE_UNKNOWN ? FF_PROFILE_AAC_LOW :
avctx - > profile ;
for ( i = 0 ; i < 16 ; i + + )
if ( avctx - > sample_rate = = avpriv_mpeg4audio_sample_rates [ i ] )
break ;
s - > samplerate_index = i ;
s - > channels = avctx - > channels ;
ERROR_IF ( i = = 16 | | i > = ff_aac_swb_size_1024_len | | i > = ff_aac_swb_size_128_len ,
ERROR_IF ( s - > samplerate_index = = 16 | |
s - > samplerate_index > = ff_aac_swb_size_1024_len | |
s - > samplerate_index > = ff_aac_swb_size_128_len ,
" Unsupported sample rate %d \n " , avctx - > sample_rate ) ;
ERROR_IF ( s - > channels > AAC_MAX_CHANNELS | | s - > channels = = 7 ,
" Unsupported number of channels: %d \n " , s - > channels ) ;
WARN_IF ( 1024.0 * avctx - > bit_rate / avctx - > sample_rate > 6144 * s - > channels ,
" Too many bits per frame requested, clamping to max \n " ) ;
if ( avctx - > profile = = FF_PROFILE_AAC_MAIN ) {
s - > options . pred = 1 ;
} else if ( ( avctx - > profile = = FF_PROFILE_AAC_LOW | |
avctx - > profile = = FF_PROFILE_UNKNOWN ) & & s - > options . pred ) {
s - > profile = 0 ; /* Main */
WARN_IF ( 1 , " Prediction requested, changing profile to AAC-Main \n " ) ;
} else if ( avctx - > profile = = FF_PROFILE_AAC_LOW | |
avctx - > profile = = FF_PROFILE_UNKNOWN ) {
s - > profile = 1 ; /* Low */
} else {
ERROR_IF ( 1 , " Unsupported profile %d \n " , avctx - > profile ) ;
for ( i = 0 ; i < FF_ARRAY_ELEMS ( aacenc_profiles ) ; i + + ) {
if ( avctx - > profile = = aacenc_profiles [ i ] . profile ) {
p_opt = & aacenc_profiles [ i ] . opts ;
break ;
}
}
ERROR_IF ( ! p_opt , " Unsupported encoding profile: %d \n " , avctx - > profile ) ;
AAC_OPT_SET ( & s - > options , p_opt , 1 , coder ) ;
AAC_OPT_SET ( & s - > options , p_opt , 0 , pns ) ;
AAC_OPT_SET ( & s - > options , p_opt , 0 , tns ) ;
AAC_OPT_SET ( & s - > options , p_opt , 0 , pred ) ;
AAC_OPT_SET ( & s - > options , p_opt , 1 , mid_side ) ;
AAC_OPT_SET ( & s - > options , p_opt , 0 , intensity_stereo ) ;
if ( avctx - > profile = = FF_PROFILE_MPEG2_AAC_LOW )
s - > profile = FF_PROFILE_AAC_LOW ;
else
s - > profile = avctx - > profile ;
s - > coder = & ff_aac_coders [ s - > options . coder ] ;
if ( s - > options . aac_coder ! = AAC_CODER_TWOLOOP ) {
if ( s - > options . coder ! = AAC_CODER_TWOLOOP ) {
s - > options . intensity_stereo = 0 ;
s - > options . pns = 0 ;
}
avctx - > bit_rate = ( int ) FFMIN (
6144 * s - > channels / 1024.0 * avctx - > sample_rate ,
avctx - > bit_rate ) ;
s - > samplerate_index = i ;
s - > chan_map = aac_chan_configs [ s - > channels - 1 ] ;
if ( ( ret = dsp_init ( avctx , s ) ) < 0 )
goto fail ;
if ( ( ret = alloc_buffers ( avctx , s ) ) < 0 )
goto fail ;
avctx - > extradata_size = 5 ;
put_audio_specific_config ( avctx ) ;
sizes [ 0 ] = ff_aac_swb_size_1024 [ i ] ;
sizes [ 1 ] = ff_aac_swb_size_128 [ i ] ;
lengths [ 0 ] = ff_aac_num_swb_1024 [ i ] ;
lengths [ 1 ] = ff_aac_num_swb_128 [ i ] ;
sizes [ 0 ] = ff_aac_swb_size_1024 [ s - > samplerate_ index ] ;
sizes [ 1 ] = ff_aac_swb_size_128 [ s - > samplerate_ index ] ;
lengths [ 0 ] = ff_aac_num_swb_1024 [ s - > samplerate_ index ] ;
lengths [ 1 ] = ff_aac_num_swb_128 [ s - > samplerate_ index ] ;
for ( i = 0 ; i < s - > chan_map [ 0 ] ; i + + )
grouping [ i ] = s - > chan_map [ i + 1 ] = = TYPE_CPE ;
if ( ( ret = ff_psy_init ( & s - > psy , avctx , 2 , sizes , lengths ,
s - > chan_map [ 0 ] , grouping ) ) < 0 )
goto fail ;
s - > psypp = ff_psy_preprocess_init ( avctx ) ;
s - > coder = & ff_aac_coders [ s - > options . aac_coder ] ;
ff_lpc_init ( & s - > lpc , 2 * avctx - > frame_size , TNS_MAX_ORDER , FF_LPC_TYPE_LEVINSON ) ;
if ( HAVE_MIPSDSPR1 )
ff_aac_coder_init_mips ( s ) ;
s - > lambda = avctx - > global_quality > 0 ? avctx - > global_quality : 120 ;
s - > random_state = 0x1f2e3d4c ;
ff_aac_tableinit ( ) ;
avctx - > initial_padding = 1024 ;
ff_af_queue_init ( avctx , & s - > afq ) ;
return 0 ;
@ -938,19 +982,16 @@ fail:
# define AACENC_FLAGS AV_OPT_FLAG_ENCODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM
static const AVOption aacenc_options [ ] = {
{ " stereo_mode " , " Stereo coding method " , offsetof ( AACEncContext , options . stereo_mode ) , AV_OPT_TYPE_INT , { . i64 = 0 } , - 1 , 1 , AACENC_FLAGS , " stereo_mode " } ,
{ " auto " , " Selected by the Encoder " , 0 , AV_OPT_TYPE_CONST , { . i64 = - 1 } , INT_MIN , INT_MAX , AACENC_FLAGS , " stereo_mode " } ,
{ " ms_off " , " Disable Mid/Side coding " , 0 , AV_OPT_TYPE_CONST , { . i64 = 0 } , INT_MIN , INT_MAX , AACENC_FLAGS , " stereo_mode " } ,
{ " ms_force " , " Force Mid/Side for the whole frame if possible " , 0 , AV_OPT_TYPE_CONST , { . i64 = 1 } , INT_MIN , INT_MAX , AACENC_FLAGS , " stereo_mode " } ,
{ " aac_coder " , " Coding algorithm " , offsetof ( AACEncContext , options . aac_coder ) , AV_OPT_TYPE_INT , { . i64 = AAC_CODER_TWOLOOP } , 0 , AAC_CODER_NB - 1 , AACENC_FLAGS , " aac_coder " } ,
{ " faac " , " FAAC-inspired method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_FAAC } , INT_MIN , INT_MAX , AACENC_FLAGS , " aac_coder " } ,
{ " anmr " , " ANMR method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_ANMR } , INT_MIN , INT_MAX , AACENC_FLAGS , " aac_coder " } ,
{ " twoloop " , " Two loop searching method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_TWOLOOP } , INT_MIN , INT_MAX , AACENC_FLAGS , " aac_coder " } ,
{ " fast " , " Constant quantizer " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_FAST } , INT_MIN , INT_MAX , AACENC_FLAGS , " aac_coder " } ,
{ " aac_pns " , " Perceptual Noise Substitution " , offsetof ( AACEncContext , options . pns ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , AACENC_FLAGS } ,
{ " aac_is " , " Intensity stereo coding " , offsetof ( AACEncContext , options . intensity_stereo ) , AV_OPT_TYPE_BOOL , { . i64 = 1 } , 0 , 1 , AACENC_FLAGS } ,
{ " aac_tns " , " Temporal noise shaping " , offsetof ( AACEncContext , options . tns ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , AACENC_FLAGS } ,
{ " aac_pred " , " AAC-Main prediction " , offsetof ( AACEncContext , options . pred ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , 0 , 1 , AACENC_FLAGS } ,
{ " aac_coder " , " Coding algorithm " , offsetof ( AACEncContext , options . coder ) , AV_OPT_TYPE_INT , { . i64 = AAC_CODER_TWOLOOP } , - 1 , AAC_CODER_NB - 1 , AACENC_FLAGS , " coder " } ,
{ " faac " , " FAAC-inspired method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_FAAC } , INT_MIN , INT_MAX , AACENC_FLAGS , " coder " } ,
{ " anmr " , " ANMR method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_ANMR } , INT_MIN , INT_MAX , AACENC_FLAGS , " coder " } ,
{ " twoloop " , " Two loop searching method " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_TWOLOOP } , INT_MIN , INT_MAX , AACENC_FLAGS , " coder " } ,
{ " fast " , " Constant quantizer " , 0 , AV_OPT_TYPE_CONST , { . i64 = AAC_CODER_FAST } , INT_MIN , INT_MAX , AACENC_FLAGS , " coder " } ,
{ " aac_ms " , " Force M/S stereo coding " , offsetof ( AACEncContext , options . mid_side ) , AV_OPT_TYPE_BOOL , { . i64 = 0 } , - 1 , 1 , AACENC_FLAGS } ,
{ " aac_is " , " Intensity stereo coding " , offsetof ( AACEncContext , options . intensity_stereo ) , AV_OPT_TYPE_BOOL , { . i64 = OPT_AUTO } , - 1 , 1 , AACENC_FLAGS } ,
{ " aac_pns " , " Perceptual noise substitution " , offsetof ( AACEncContext , options . pns ) , AV_OPT_TYPE_BOOL , { . i64 = OPT_AUTO } , - 1 , 1 , AACENC_FLAGS } ,
{ " aac_tns " , " Temporal noise shaping " , offsetof ( AACEncContext , options . tns ) , AV_OPT_TYPE_BOOL , { . i64 = OPT_AUTO } , - 1 , 1 , AACENC_FLAGS } ,
{ " aac_pred " , " AAC-Main prediction " , offsetof ( AACEncContext , options . pred ) , AV_OPT_TYPE_BOOL , { . i64 = OPT_AUTO } , - 1 , 1 , AACENC_FLAGS } ,
{ NULL }
} ;