[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