[FFmpeg-soc] [soc]: r2431 - in aacenc: aacenc.c aacpsy.c
kostya
subversion at mplayerhq.hu
Sat Jun 14 09:54:04 CEST 2008
Author: kostya
Date: Sat Jun 14 09:54:03 2008
New Revision: 2431
Log:
Rudimentary M/S detection
Modified:
aacenc/aacenc.c
aacenc/aacpsy.c
Modified: aacenc/aacenc.c
==============================================================================
--- aacenc/aacenc.c (original)
+++ aacenc/aacenc.c Sat Jun 14 09:54:03 2008
@@ -235,6 +235,20 @@ static void put_ics_info(AVCodecContext
}
/**
+ * Encode MS data.
+ * @see 4.6.8.1
+ */
+static void encode_ms_info(PutBitContext *pb, cpe_struct *cpe)
+{
+ int i;
+
+ put_bits(pb, 2, cpe->ms.present);
+ if(cpe->ms.present == 1)
+ for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
+ put_bits(pb, 1, cpe->ms.mask[0][i]);
+}
+
+/**
* Scan spectral band and determine optimal codebook for it.
*/
static int determine_section_info(AACEncContext *s, cpe_struct *cpe, int channel, int start, int size)
@@ -402,13 +416,6 @@ static int aac_encode_frame(AVCodecConte
analyze(avctx, s, &s->cpe, samples, 1);
ff_aac_psy_analyze(&s->psy, samples, 0, &s->cpe);
- if(avctx->channels > 1){
- s->cpe.common_window = s->cpe.ch[0].ics.window_shape == s->cpe.ch[1].ics.window_shape;
- if(s->cpe.common_window){
- s->cpe.ch[0].ics.max_sfb = FFMAX(s->cpe.ch[0].ics.max_sfb, s->cpe.ch[1].ics.max_sfb);
- s->cpe.ch[1].ics.max_sfb = s->cpe.ch[0].ics.max_sfb;
- }
- }
init_put_bits(&s->pb, frame, buf_size*8);
//output encoded
@@ -424,7 +431,7 @@ static int aac_encode_frame(AVCodecConte
put_bits(&s->pb, 1, s->cpe.common_window);
if(s->cpe.common_window){
put_ics_info(avctx, &s->cpe.ch[0].ics);
- put_bits(&s->pb, 2, 0); //no MS mode for now
+ encode_ms_info(&s->pb, &s->cpe);
}
encode_individual_channel(avctx, &s->cpe, 0);
encode_individual_channel(avctx, &s->cpe, 1);
Modified: aacenc/aacpsy.c
==============================================================================
--- aacenc/aacpsy.c (original)
+++ aacenc/aacpsy.c Sat Jun 14 09:54:03 2008
@@ -44,6 +44,7 @@ static void psy_null_window(AACPsyContex
cpe->ch[ch].ics.window_sequence = 0;
cpe->ch[ch].ics.window_shape = 1;
}
+ cpe->common_window = cpe->ch[0].ics.window_shape == cpe->ch[1].ics.window_shape;
}
static void psy_null_process(AACPsyContext *apc, int16_t *audio, int channel, cpe_struct *cpe)
@@ -51,12 +52,30 @@ static void psy_null_process(AACPsyConte
int start, sum, maxsfb;
int ch, g, i;
+ //detect M/S
+ if(apc->avctx->channels > 1 && cpe->common_window){
+ start = 0;
+ for(g = 0; g < apc->num_bands; g++){
+ float diff = 0.0f;
+
+ for(i = 0; i < apc->bands[g]; i++)
+ diff += fabs(cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i]);
+ cpe->ms.mask[0][g] = diff == 0.0;
+ }
+ }
for(ch = 0; ch < apc->avctx->channels; ch++){
start = 0;
cpe->ch[ch].gain = SCALE_ONE_POS;
for(g = 0; g < apc->num_bands; g++){
sum = 0;
cpe->ch[ch].sf_idx[g] = SCALE_ONE_POS;
+ //apply M/S
+ if(!ch && cpe->ms.mask[0][g]){
+ for(i = 0; i < apc->bands[g]; i++){
+ cpe->ch[0].coeffs[start+i] = (cpe->ch[0].coeffs[start+i] + cpe->ch[1].coeffs[start+i]) / 2.0;
+ cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].coeffs[start+i];
+ }
+ }
for(i = 0; i < apc->bands[g]; i++){
cpe->ch[ch].icoefs[start+i] = av_clip((int)(roundf(cpe->ch[ch].coeffs[start+i] / pow2sf_tab[cpe->ch[ch].sf_idx[g]+60])), -8191, 8191);
sum += !!cpe->ch[ch].icoefs[start+i];
@@ -67,6 +86,15 @@ static void psy_null_process(AACPsyConte
for(maxsfb = apc->num_bands; maxsfb > 0 && cpe->ch[ch].zeroes[maxsfb-1]; maxsfb--);
cpe->ch[ch].ics.max_sfb = maxsfb;
}
+ if(apc->avctx->channels > 1 && cpe->common_window){
+ int msc = 0;
+ cpe->ch[0].ics.max_sfb = FFMAX(cpe->ch[0].ics.max_sfb, cpe->ch[1].ics.max_sfb);
+ cpe->ch[1].ics.max_sfb = cpe->ch[0].ics.max_sfb;
+ for(i = 0; i < cpe->ch[0].ics.max_sfb; i++)
+ if(cpe->ms.mask[0][i]) msc++;
+ if(msc == 0 || cpe->ch[0].ics.max_sfb == 0) cpe->ms.present = 0;
+ else cpe->ms.present = msc < cpe->ch[0].ics.max_sfb ? 1 : 2;
+ }
}
static const AACPsyModel psy_models[AAC_NB_PSY_MODELS] =
More information about the FFmpeg-soc
mailing list