ac3enc: Add codec-specific options for writing AC-3 metadata.
[ffmpeg.git] / libavcodec / ac3enc_fixed.c
index dfd218e..967c7f0 100644 (file)
@@ -4,20 +4,20 @@
  * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
  * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
  *
- * This file is part of FFmpeg.
+ * This file is part of Libav.
  *
- * FFmpeg is free software; you can redistribute it and/or
+ * Libav is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  *
- * FFmpeg is distributed in the hope that it will be useful,
+ * Libav is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  *
  * You should have received a copy of the GNU Lesser General Public
- * License along with FFmpeg; if not, write to the Free Software
+ * License along with Libav; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 
@@ -131,10 +131,10 @@ mdct_alloc_fail:
 
 
 /** Complex multiply */
-#define CMUL(pre, pim, are, aim, bre, bim)              \
+#define CMUL(pre, pim, are, aim, bre, bim, rshift)      \
 {                                                       \
-   pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15;     \
-   pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15;     \
+   pre = (MUL16(are, bre) - MUL16(aim, bim)) >> rshift; \
+   pim = (MUL16(are, bim) + MUL16(bre, aim)) >> rshift; \
 }
 
 
@@ -195,7 +195,7 @@ static void fft(AC3MDCTContext *mdct, IComplex *z, int ln)
             p++;
             q++;
             for(l = nblocks; l < np2; l += nblocks) {
-                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
+                CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im, 15);
                 BF(p->re, p->im, q->re,  q->im,
                    p->re, p->im, tmp_re, tmp_im);
                 p++;
@@ -234,7 +234,7 @@ static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in)
     for (i = 0; i < n4; i++) {
         re =  ((int)rot[   2*i] - (int)rot[ n-1-2*i]) >> 1;
         im = -((int)rot[n2+2*i] - (int)rot[n2-1-2*i]) >> 1;
-        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
+        CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i], 15);
     }
 
     fft(mdct, x, mdct->nbits - 2);
@@ -243,7 +243,7 @@ static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in)
     for (i = 0; i < n4; i++) {
         re = x[i].re;
         im = x[i].im;
-        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]);
+        CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i], 0);
     }
 }
 
@@ -252,15 +252,9 @@ static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in)
  * Apply KBD window to input samples prior to MDCT.
  */
 static void apply_window(DSPContext *dsp, int16_t *output, const int16_t *input,
-                         const int16_t *window, int n)
+                         const int16_t *window, unsigned int len)
 {
-    int i;
-    int n2 = n >> 1;
-
-    for (i = 0; i < n2; i++) {
-        output[i]     = MUL16(input[i],     window[i]) >> 15;
-        output[n-i-1] = MUL16(input[n-i-1], window[i]) >> 15;
-    }
+    dsp->apply_window_int16(output, input, window, len);
 }
 
 
@@ -270,63 +264,43 @@ static void apply_window(DSPContext *dsp, int16_t *output, const int16_t *input,
  * @param n   number of values in the array
  * @return    log2(max(abs(tab[])))
  */
-static int log2_tab(int16_t *tab, int n)
+static int log2_tab(AC3EncodeContext *s, int16_t *src, int len)
 {
-    int i, v;
-
-    v = 0;
-    for (i = 0; i < n; i++)
-        v |= abs(tab[i]);
-
+    int v = s->ac3dsp.ac3_max_msb_abs_int16(src, len);
     return av_log2(v);
 }
 
 
 /**
- * Left-shift each value in an array by a specified amount.
- * @param tab    input array
- * @param n      number of values in the array
- * @param lshift left shift amount. a negative value means right shift.
- */
-static void lshift_tab(int16_t *tab, int n, int lshift)
-{
-    int i;
-
-    if (lshift > 0) {
-        for (i = 0; i < n; i++)
-            tab[i] <<= lshift;
-    } else if (lshift < 0) {
-        lshift = -lshift;
-        for (i = 0; i < n; i++)
-            tab[i] >>= lshift;
-    }
-}
-
-
-/**
  * Normalize the input samples to use the maximum available precision.
- * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
- * match the 24-bit internal precision for MDCT coefficients.
+ * This assumes signed 16-bit input samples.
  *
  * @return exponent shift
  */
 static int normalize_samples(AC3EncodeContext *s)
 {
-    int v = 14 - log2_tab(s->windowed_samples, AC3_WINDOW_SIZE);
-    v = FFMAX(0, v);
-    lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v);
-    return v - 9;
+    int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE);
+    if (v > 0)
+        s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v);
+    /* +6 to right-shift from 31-bit to 25-bit */
+    return v + 6;
 }
 
 
 /**
- * Scale MDCT coefficients from float to fixed-point.
+ * Scale MDCT coefficients to 25-bit signed fixed-point.
  */
 static void scale_coefficients(AC3EncodeContext *s)
 {
-    /* scaling/conversion is obviously not needed for the fixed-point encoder
-       since the coefficients are already fixed-point. */
-    return;
+    int blk, ch;
+
+    for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+        AC3Block *block = &s->blocks[blk];
+        for (ch = 0; ch < s->channels; ch++) {
+            s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS,
+                                       block->coeff_shift[ch]);
+        }
+    }
 }
 
 
@@ -425,7 +399,7 @@ int main(void)
 #endif /* TEST */
 
 
-AVCodec ac3_fixed_encoder = {
+AVCodec ff_ac3_fixed_encoder = {
     "ac3_fixed",
     AVMEDIA_TYPE_AUDIO,
     CODEC_ID_AC3,
@@ -436,5 +410,6 @@ AVCodec ac3_fixed_encoder = {
     NULL,
     .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_S16,AV_SAMPLE_FMT_NONE},
     .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"),
+    .priv_class = &ac3enc_class,
     .channel_layouts = ac3_channel_layouts,
 };