]> git.sesse.net Git - ffmpeg/blobdiff - libavcodec/aac.c
Work around GCC variable may be used uninitialised warning
[ffmpeg] / libavcodec / aac.c
index 7dd0c5ea8b147df1d3e52d08c4a52e5935412fbf..26d860adf659d929c2289a2af2e838182a1915ae 100644 (file)
@@ -118,7 +118,7 @@ static int output_configure(AACContext *ac, enum ChannelPosition che_pos[4][MAX_
      * Set up default 1:1 output mapping.
      *
      * For a 5.1 stream the output order will be:
-     *    [ Front Left ] [ Front Right ] [ Center ] [ LFE ] [ Surround Left ] [ Surround Right ]
+     *    [ Center ] [ Front Left ] [ Front Right ] [ LFE ] [ Surround Left ] [ Surround Right ]
      */
 
     for(i = 0; i < MAX_ELEM_ID; i++) {
@@ -604,6 +604,43 @@ static void decode_pulses(Pulse * pulse, GetBitContext * gb, const uint16_t * sw
     }
 }
 
+/**
+ * Decode Temporal Noise Shaping data; reference: table 4.48.
+ *
+ * @return  Returns error status. 0 - OK, !0 - error
+ */
+static int decode_tns(AACContext * ac, TemporalNoiseShaping * tns,
+        GetBitContext * gb, const IndividualChannelStream * ics) {
+    int w, filt, i, coef_len, coef_res, coef_compress;
+    const int is8 = ics->window_sequence[0] == EIGHT_SHORT_SEQUENCE;
+    const int tns_max_order = is8 ? 7 : ac->m4ac.object_type == AOT_AAC_MAIN ? 20 : 12;
+    for (w = 0; w < ics->num_windows; w++) {
+        if ((tns->n_filt[w] = get_bits(gb, 2 - is8))) {
+            coef_res = get_bits1(gb);
+
+        for (filt = 0; filt < tns->n_filt[w]; filt++) {
+            int tmp2_idx;
+            tns->length[w][filt] = get_bits(gb, 6 - 2*is8);
+
+            if ((tns->order[w][filt] = get_bits(gb, 5 - 2*is8)) > tns_max_order) {
+                av_log(ac->avccontext, AV_LOG_ERROR, "TNS filter order %d is greater than maximum %d.",
+                       tns->order[w][filt], tns_max_order);
+                tns->order[w][filt] = 0;
+                return -1;
+            }
+            tns->direction[w][filt] = get_bits1(gb);
+            coef_compress = get_bits1(gb);
+            coef_len = coef_res + 3 - coef_compress;
+            tmp2_idx = 2*coef_compress + coef_res;
+
+            for (i = 0; i < tns->order[w][filt]; i++)
+                tns->coef[w][filt][i] = tns_tmp2_map[tmp2_idx][get_bits(gb, coef_len)];
+        }
+        }
+    }
+    return 0;
+}
+
 /**
  * Decode Mid/Side data; reference: table 4.54.
  *
@@ -1066,6 +1103,61 @@ static int decode_extension_payload(AACContext * ac, GetBitContext * gb, int cnt
     return res;
 }
 
+/**
+ * Decode Temporal Noise Shaping filter coefficients and apply all-pole filters; reference: 4.6.9.3.
+ *
+ * @param   decode  1 if tool is used normally, 0 if tool is used in LTP.
+ * @param   coef    spectral coefficients
+ */
+static void apply_tns(float coef[1024], TemporalNoiseShaping * tns, IndividualChannelStream * ics, int decode) {
+    const int mmm = FFMIN(ics->tns_max_bands,  ics->max_sfb);
+    int w, filt, m, i;
+    int bottom, top, order, start, end, size, inc;
+    float lpc[TNS_MAX_ORDER];
+
+    for (w = 0; w < ics->num_windows; w++) {
+        bottom = ics->num_swb;
+        for (filt = 0; filt < tns->n_filt[w]; filt++) {
+            top    = bottom;
+            bottom = FFMAX(0, top - tns->length[w][filt]);
+            order  = tns->order[w][filt];
+            if (order == 0)
+                continue;
+
+            /* tns_decode_coef
+             * FIXME: This duplicates the functionality of some double code in lpc.c.
+             */
+            for (m = 0; m < order; m++) {
+                float tmp;
+                lpc[m] = tns->coef[w][filt][m];
+                for (i = 0; i < m/2; i++) {
+                    tmp = lpc[i];
+                    lpc[i]     += lpc[m] * lpc[m-1-i];
+                    lpc[m-1-i] += lpc[m] * tmp;
+                }
+                if(m & 1)
+                    lpc[i]     += lpc[m] * lpc[i];
+            }
+
+            start = ics->swb_offset[FFMIN(bottom, mmm)];
+            end   = ics->swb_offset[FFMIN(   top, mmm)];
+            if ((size = end - start) <= 0)
+                continue;
+            if (tns->direction[w][filt]) {
+                inc = -1; start = end - 1;
+            } else {
+                inc = 1;
+            }
+            start += w * 128;
+
+            // ar filter
+            for (m = 0; m < size; m++, start += inc)
+                for (i = 1; i <= FFMIN(m, order); i++)
+                    coef[start] -= coef[start - i*inc] * lpc[i-1];
+        }
+    }
+}
+
 /**
  * Conduct IMDCT and windowing.
  */