[FFmpeg-devel] [PATCH 07/11] aacenc: add support for coding of IS spectral coefficients

Rostislav Pehlivanov atomnuker at gmail.com
Fri Jun 26 22:16:36 CEST 2015


This commit adds support for the coding of intensity stereo spectral coefficients. It also fixes the Mid/Side coding of band_types higher than RESERVED_BT (M/S must not be applied to their spectral coefficients, but marking M/S as present in encode_ms_info() is okay). Much of the changes here were taken from the decoder and inverted. This commit does not change the functionality of the decoder.
---
 libavcodec/aacenc.c | 39 +++++++++++++++++++++++++++++----------
 1 file changed, 29 insertions(+), 10 deletions(-)

diff --git a/libavcodec/aacenc.c b/libavcodec/aacenc.c
index 3a512ff..a2ff04f 100644
--- a/libavcodec/aacenc.c
+++ b/libavcodec/aacenc.c
@@ -312,19 +312,28 @@ static void encode_ms_info(PutBitContext *pb, ChannelElement *cpe)
 static void adjust_frame_information(ChannelElement *cpe, int chans)
 {
     int i, w, w2, g, ch;
-    int start, maxsfb, cmaxsfb;
+    int maxsfb, cmaxsfb;
+    IndividualChannelStream *ics;
 
-    for (ch = 0; ch < chans; ch++) {
-        IndividualChannelStream *ics = &cpe->ch[ch].ics;
-        start = 0;
-        maxsfb = 0;
-        cpe->ch[ch].pulse.num_pulse = 0;
+    if (cpe->common_window) {
+        ics = &cpe->ch[0].ics;
         for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
-            for (w2 = 0; w2 < ics->group_len[w]; w2++) {
-                start = (w+w2) * 128;
+            for (w2 =  0; w2 < ics->group_len[w]; w2++) {
+                int start = (w+w2) * 128;
                 for (g = 0; g < ics->num_swb; g++) {
-                    //apply M/S
-                    if (cpe->common_window && !ch && cpe->ms_mask[w*16 + g]) {
+                    //apply Intensity stereo coeffs transformation
+                    if (cpe->is_mask[w*16 + g]) {
+                        int p = -1 + 2 * (cpe->ch[1].band_type[w*16+g] - 14);
+                        float scale = sqrtf(cpe->ch[0].is_ener[w*16+g]*cpe->ch[1].is_ener[w*16+g]);
+                        if (cpe->ms_mask[w*16 + g])
+                            p *= 1 - 2 * cpe->ms_mask[w*16 + g];
+                        for (i = 0; i < ics->swb_sizes[g]; i++) {
+                            cpe->ch[0].coeffs[start+i] = (cpe->ch[0].pcoeffs[start+i] + p*cpe->ch[1].pcoeffs[start+i]) * scale;
+                            cpe->ch[1].coeffs[start+i] = 0.0f;
+                        }
+                    } else if (cpe->ms_mask[w*16 + g] &&
+                               cpe->ch[0].band_type[w*16 + g] < NOISE_BT &&
+                               cpe->ch[1].band_type[w*16 + g] < NOISE_BT) {
                         for (i = 0; i < ics->swb_sizes[g]; i++) {
                             cpe->ch[0].coeffs[start+i] = (cpe->ch[0].pcoeffs[start+i] + cpe->ch[1].pcoeffs[start+i]) * 0.5f;
                             cpe->ch[1].coeffs[start+i] = cpe->ch[0].coeffs[start+i] - cpe->ch[1].pcoeffs[start+i];
@@ -332,6 +341,16 @@ static void adjust_frame_information(ChannelElement *cpe, int chans)
                     }
                     start += ics->swb_sizes[g];
                 }
+            }
+        }
+    }
+
+    for (ch = 0; ch < chans; ch++) {
+        IndividualChannelStream *ics = &cpe->ch[ch].ics;
+        maxsfb = 0;
+        cpe->ch[ch].pulse.num_pulse = 0;
+        for (w = 0; w < ics->num_windows; w += ics->group_len[w]) {
+            for (w2 =  0; w2 < ics->group_len[w]; w2++) {
                 for (cmaxsfb = ics->num_swb; cmaxsfb > 0 && cpe->ch[ch].zeroes[w*16+cmaxsfb-1]; cmaxsfb--)
                     ;
                 maxsfb = FFMAX(maxsfb, cmaxsfb);
-- 
2.1.4



More information about the ffmpeg-devel mailing list