@ -76,6 +76,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
int refbits = destbits ;
int toomanybits , toofewbits ;
char nzs [ 128 ] ;
uint8_t nextband [ 128 ] ;
int maxsf [ 128 ] ;
float dists [ 128 ] = { 0 } , qenergies [ 128 ] = { 0 } , uplims [ 128 ] , euplims [ 128 ] , energies [ 128 ] ;
float maxvals [ 128 ] , spread_thr_r [ 128 ] ;
@ -102,7 +103,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
*/
float sfoffs = av_clipf ( log2f ( 120.0f / lambda ) * 4.0f , - 5 , 10 ) ;
int fflag , minscaler , maxscaler , nminscaler , minrdsf ;
int fflag , minscaler , maxscaler , nminscaler ;
int its = 0 ;
int maxits = 30 ;
int allz = 0 ;
@ -158,9 +159,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
/** search further */
maxits * = 2 ;
} else {
/** When using ABR, be strict */
toomanybits = destbits + destbits / 16 ;
toofewbits = destbits - destbits / 4 ;
/* When using ABR, be strict, but a reasonable leeway is
* critical to allow RC to smoothly track desired bitrate
* without sudden quality drops that cause audible artifacts .
* Symmetry is also desirable , to avoid systematic bias .
*/
toomanybits = destbits + destbits / 8 ;
toofewbits = destbits - destbits / 8 ;
sfoffs = 0 ;
rdlambda = sqrtf ( rdlambda ) ;
@ -191,6 +196,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
bandwidth = avctx - > cutoff ;
} else {
bandwidth = FFMAX ( 3000 , AAC_CUTOFF_FROM_BITRATE ( frame_bit_rate , 1 , avctx - > sample_rate ) ) ;
s - > psy . cutoff = bandwidth ;
}
cutoff = bandwidth * 2 * wlen / avctx - > sample_rate ;
@ -241,7 +247,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
nzs [ w * 16 + g ] = nz ;
sce - > zeroes [ w * 16 + g ] = ! nz ;
allz | = nz ;
if ( nz ) {
if ( nz & & sce - > can_pns [ w * 16 + g ] ) {
spread_thr_r [ w * 16 + g ] = energy * nz / ( uplim * spread ) ;
if ( min_spread_thr_r < 0 ) {
min_spread_thr_r = max_spread_thr_r = spread_thr_r [ w * 16 + g ] ;
@ -433,6 +439,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
} while ( qstep ) ;
overdist = 1 ;
fflag = tbits < toofewbits ;
for ( i = 0 ; i < 2 & & ( overdist | | recomprd ) ; + + i ) {
if ( recomprd ) {
/** Must recompute distortion */
@ -484,13 +491,13 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
}
}
}
if ( ! i & & s - > options . pns & & its > maxits / 2 ) {
if ( ! i & & s - > options . pns & & its > maxits / 2 & & tbits > toofewbits ) {
float maxoverdist = 0.0f ;
float ovrfactor = 1.f + ( maxits - its ) * 16.f / maxits ;
overdist = recomprd = 0 ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
float ovrfactor = 2.f + ( maxits - its ) * 16.f / maxits ;
for ( g = start = 0 ; g < sce - > ics . num_swb ; start + = sce - > ics . swb_sizes [ g + + ] ) {
if ( ! sce - > zeroes [ w * 16 + g ] & & dists [ w * 16 + g ] > uplims [ w * 16 + g ] * ovrfactor ) {
if ( ! sce - > zeroes [ w * 16 + g ] & & sce - > sf_idx [ w * 16 + g ] > SCALE_ONE_POS & & dists [ w * 16 + g ] > uplims [ w * 16 + g ] * ovrfactor ) {
float ovrdist = dists [ w * 16 + g ] / FFMAX ( uplims [ w * 16 + g ] , euplims [ w * 16 + g ] ) ;
maxoverdist = FFMAX ( maxoverdist , ovrdist ) ;
overdist + + ;
@ -506,7 +513,7 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
float zspread ;
int zeroable = 0 ;
int zeroed = 0 ;
int maxzeroed ;
int maxzeroed , zloop ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
for ( g = start = 0 ; g < sce - > ics . num_swb ; start + = sce - > ics . swb_sizes [ g + + ] ) {
if ( start > = pns_start_pos & & ! sce - > zeroes [ w * 16 + g ] & & sce - > can_pns [ w * 16 + g ] ) {
@ -517,21 +524,41 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
}
}
zspread = ( maxspread - minspread ) * 0.0125f + minspread ;
zspread = FFMIN ( maxoverdist , zspread ) ;
maxzeroed = zeroable * its / ( 2 * maxits ) ;
for ( g = sce - > ics . num_swb - 1 ; g > 0 & & zeroed < maxzeroed ; g - - ) {
if ( sce - > ics . swb_offset [ g ] < pns_start_pos )
continue ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
if ( ! sce - > zeroes [ w * 16 + g ] & & sce - > can_pns [ w * 16 + g ] & & spread_thr_r [ w * 16 + g ] < = zspread ) {
sce - > zeroes [ w * 16 + g ] = 1 ;
sce - > band_type [ w * 16 + g ] = 0 ;
zeroed + + ;
/* Don't PNS everything even if allowed. It suppresses bit starvation signals from RC,
* and forced the hand of the later search_for_pns step .
* Instead , PNS a fraction of the spread_thr_r range depending on how starved for bits we are ,
* and leave further PNSing to search_for_pns if worthwhile .
*/
zspread = FFMIN3 ( min_spread_thr_r * 8.f , zspread ,
( ( toomanybits - tbits ) * min_spread_thr_r + ( tbits - toofewbits ) * max_spread_thr_r ) / ( toomanybits - toofewbits + 1 ) ) ;
maxzeroed = FFMIN ( zeroable , FFMAX ( 1 , ( zeroable * its + maxits - 1 ) / ( 2 * maxits ) ) ) ;
for ( zloop = 0 ; zloop < 2 ; zloop + + ) {
/* Two passes: first distorted stuff - two birds in one shot and all that,
* then anything viable . Viable means not zero , but either CB = zero - able
* ( too high SF ) , not SF < = 1 ( that means we ' d be operating at very high
* quality , we don ' t want PNS when doing VHQ ) , PNS allowed , and within
* the lowest ranking percentile .
*/
float loopovrfactor = ( zloop ) ? 1.0f : ovrfactor ;
int loopminsf = ( zloop ) ? ( SCALE_ONE_POS - SCALE_DIV_512 ) : SCALE_ONE_POS ;
int mcb ;
for ( g = sce - > ics . num_swb - 1 ; g > 0 & & zeroed < maxzeroed ; g - - ) {
if ( sce - > ics . swb_offset [ g ] < pns_start_pos )
continue ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
if ( ! sce - > zeroes [ w * 16 + g ] & & sce - > can_pns [ w * 16 + g ] & & spread_thr_r [ w * 16 + g ] < = zspread
& & sce - > sf_idx [ w * 16 + g ] > loopminsf
& & ( dists [ w * 16 + g ] > loopovrfactor * uplims [ w * 16 + g ] | | ! ( mcb = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) )
| | ( mcb < = 1 & & dists [ w * 16 + g ] > FFMIN ( uplims [ w * 16 + g ] , euplims [ w * 16 + g ] ) ) ) ) {
sce - > zeroes [ w * 16 + g ] = 1 ;
sce - > band_type [ w * 16 + g ] = 0 ;
zeroed + + ;
}
}
}
}
if ( zeroed )
recomprd = 1 ;
recomprd = fflag = 1 ;
} else {
overdist = 0 ;
}
@ -549,9 +576,8 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
}
}
fflag = 0 ;
minscaler = nminscaler = av_clip ( minscaler , SCALE_ONE_POS - SCALE_DIV_512 , SCALE_MAX_POS - SCALE_DIV_512 ) ;
minrdsf = FFMAX3 ( 60 , minscaler - 1 , maxscaler - SCALE_MAX_DIFF - 1 ) ;
prev = - 1 ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
/** Start with big steps, end up fine-tunning */
int depth = ( its > maxits / 2 ) ? ( ( its > maxits * 2 / 3 ) ? 1 : 3 ) : 10 ;
@ -561,19 +587,22 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
start = w * 128 ;
for ( g = 0 ; g < sce - > ics . num_swb ; g + + ) {
int prevsc = sce - > sf_idx [ w * 16 + g ] ;
int minrdsfboost = ( sce - > ics . num_windows > 1 ) ? av_clip ( g - 4 , - 2 , 0 ) : av_clip ( g - 16 , - 4 , 0 ) ;
if ( prev < 0 & & ! sce - > zeroes [ w * 16 + g ] )
prev = sce - > sf_idx [ 0 ] ;
if ( ! sce - > zeroes [ w * 16 + g ] ) {
const float * coefs = sce - > coeffs + start ;
const float * scaled = s - > scoefs + start ;
int cmb = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) ;
if ( ( ! cmb | | dists [ w * 16 + g ] > uplims [ w * 16 + g ] ) & & sce - > sf_idx [ w * 16 + g ] > minrdsf ) {
int mindeltasf = FFMAX ( 0 , prev - SCALE_MAX_DIFF ) ;
int maxdeltasf = FFMIN ( SCALE_MAX_POS - SCALE_DIV_512 , prev + SCALE_MAX_DIFF ) ;
if ( ( ! cmb | | dists [ w * 16 + g ] > uplims [ w * 16 + g ] ) & & sce - > sf_idx [ w * 16 + g ] > mindeltasf ) {
/* Try to make sure there is some energy in every nonzero band
* NOTE : This algorithm must be forcibly imbalanced , pushing harder
* on holes or more distorted bands at first , otherwise there ' s
* no net gain ( since the next iteration will offset all bands
* on the opposite direction to compensate for extra bits )
*/
for ( i = 0 ; i < edepth ; + + i ) {
for ( i = 0 ; i < edepth & & sce - > sf_idx [ w * 16 + g ] > mindeltasf ; + + i ) {
int cb , bits ;
float dist , qenergy ;
int mb = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] - 1 ) ;
@ -585,6 +614,12 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
} else if ( i > = depth & & dists [ w * 16 + g ] < euplims [ w * 16 + g ] ) {
break ;
}
/* !g is the DC band, it's important, since quantization error here
* applies to less than a cycle , it creates horrible intermodulation
* distortion if it doesn ' t stick to what psy requests
*/
if ( ! g & & sce - > ics . num_windows > 1 & & dists [ w * 16 + g ] > = euplims [ w * 16 + g ] )
maxsf [ w * 16 + g ] = FFMIN ( sce - > sf_idx [ w * 16 + g ] , maxsf [ w * 16 + g ] ) ;
for ( w2 = 0 ; w2 < sce - > ics . group_len [ w ] ; w2 + + ) {
int b ;
float sqenergy ;
@ -603,19 +638,19 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
sce - > sf_idx [ w * 16 + g ] - - ;
dists [ w * 16 + g ] = dist - bits ;
qenergies [ w * 16 + g ] = qenergy ;
if ( mb & & ( sce - > sf_idx [ w * 16 + g ] < ( minrdsf + minrdsfboost ) | | (
if ( mb & & ( sce - > sf_idx [ w * 16 + g ] < mindeltasf | | (
( dists [ w * 16 + g ] < FFMIN ( uplmax * uplims [ w * 16 + g ] , euplims [ w * 16 + g ] ) )
& & ( fabsf ( qenergies [ w * 16 + g ] - energies [ w * 16 + g ] ) < euplims [ w * 16 + g ] )
) ) ) {
break ;
}
}
} else if ( tbits > toofewbits & & sce - > sf_idx [ w * 16 + g ] < maxscaler
} else if ( tbits > toofewbits & & sce - > sf_idx [ w * 16 + g ] < FFMIN ( maxdeltasf , maxsf [ w * 16 + g ] )
& & ( dists [ w * 16 + g ] < FFMIN ( euplims [ w * 16 + g ] , uplims [ w * 16 + g ] ) )
& & ( fabsf ( qenergies [ w * 16 + g ] - energies [ w * 16 + g ] ) < euplims [ w * 16 + g ] )
) {
/** Um... over target. Save bits for more important stuff. */
for ( i = 0 ; i < depth ; + + i ) {
for ( i = 0 ; i < depth & & sce - > sf_idx [ w * 16 + g ] < maxdeltasf ; + + i ) {
int cb , bits ;
float dist , qenergy ;
cb = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] + 1 ) ;
@ -651,38 +686,53 @@ static void search_for_quantizers_twoloop(AVCodecContext *avctx,
}
}
}
prev = sce - > sf_idx [ w * 16 + g ] = av_clip ( sce - > sf_idx [ w * 16 + g ] , mindeltasf , maxdeltasf ) ;
if ( sce - > sf_idx [ w * 16 + g ] ! = prevsc )
fflag = 1 ;
nminscaler = FFMIN ( nminscaler , sce - > sf_idx [ w * 16 + g ] ) ;
sce - > band_type [ w * 16 + g ] = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) ;
}
sce - > sf_idx [ w * 16 + g ] = av_clip ( sce - > sf_idx [ w * 16 + g ] , minrdsf , minscaler + SCALE_MAX_DIFF ) ;
sce - > sf_idx [ w * 16 + g ] = FFMIN ( sce - > sf_idx [ w * 16 + g ] , SCALE_MAX_POS - SCALE_DIV_512 ) ;
if ( sce - > sf_idx [ w * 16 + g ] ! = prevsc )
fflag = 1 ;
nminscaler = FFMIN ( nminscaler , sce - > sf_idx [ w * 16 + g ] ) ;
sce - > band_type [ w * 16 + g ] = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) ;
start + = sce - > ics . swb_sizes [ g ] ;
}
}
if ( nminscaler < minscaler | | sce - > ics . num_windows > 1 ) {
/** SF difference limit violation risk. Must re-clamp. */
minscaler = nminscaler ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
for ( g = 0 ; g < sce - > ics . num_swb ; g + + ) {
sce - > sf_idx [ w * 16 + g ] = av_clip ( sce - > sf_idx [ w * 16 + g ] , minscaler , minscaler + SCALE_MAX_DIFF ) ;
/** SF difference limit violation risk. Must re-clamp. */
prev = - 1 ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
for ( g = 0 ; g < sce - > ics . num_swb ; g + + ) {
if ( ! sce - > zeroes [ w * 16 + g ] ) {
int prevsf = sce - > sf_idx [ w * 16 + g ] ;
if ( prev < 0 )
prev = prevsf ;
sce - > sf_idx [ w * 16 + g ] = av_clip ( sce - > sf_idx [ w * 16 + g ] , prev - SCALE_MAX_DIFF , prev + SCALE_MAX_DIFF ) ;
sce - > band_type [ w * 16 + g ] = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) ;
prev = sce - > sf_idx [ w * 16 + g ] ;
if ( ! fflag & & prevsf ! = sce - > sf_idx [ w * 16 + g ] )
fflag = 1 ;
}
}
}
its + + ;
} while ( fflag & & its < maxits ) ;
/** Scout out next nonzero bands */
ff_init_nextband_map ( sce , nextband ) ;
prev = - 1 ;
for ( w = 0 ; w < sce - > ics . num_windows ; w + = sce - > ics . group_len [ w ] ) {
/** Make sure proper codebooks are set */
for ( g = start = 0 ; g < sce - > ics . num_swb ; start + = sce - > ics . swb_sizes [ g + + ] ) {
for ( g = 0 ; g < sce - > ics . num_swb ; g + + ) {
if ( ! sce - > zeroes [ w * 16 + g ] ) {
sce - > band_type [ w * 16 + g ] = find_min_book ( maxvals [ w * 16 + g ] , sce - > sf_idx [ w * 16 + g ] ) ;
if ( sce - > band_type [ w * 16 + g ] < = 0 ) {
sce - > zeroes [ w * 16 + g ] = 1 ;
sce - > band_type [ w * 16 + g ] = 0 ;
if ( ! ff_sfdelta_can_remove_band ( sce , nextband , prev , w * 16 + g ) ) {
/** Cannot zero out, make sure it's not attempted */
sce - > band_type [ w * 16 + g ] = 1 ;
} else {
sce - > zeroes [ w * 16 + g ] = 1 ;
sce - > band_type [ w * 16 + g ] = 0 ;
}
}
} else {
sce - > band_type [ w * 16 + g ] = 0 ;