Also configure fixed-point encoding with --disable-ac3enc-float.
Make floating-point the default and use it in the regression test.
---
configure | 5 +
libavcodec/ac3enc.c | 341 +-------------------------------------------
libavcodec/ac3enc_fixed.c | 267 +++++++++++++++++++++++++++++++++++
libavcodec/ac3enc_fixed.h | 57 ++++++++
libavcodec/ac3enc_float.c | 61 ++++++++
libavcodec/ac3enc_float.h | 50 +++++++
tests/codec-regression.sh | 5 +-
tests/ref/acodec/ac3 | 4 +-
8 files changed, 453 insertions(+), 337 deletions(-)
create mode 100644 libavcodec/ac3enc_fixed.c
create mode 100644 libavcodec/ac3enc_fixed.h
create mode 100644 libavcodec/ac3enc_float.c
create mode 100644 libavcodec/ac3enc_float.h
diff --git configure configure
index 99920ab..b79c847 100755
--- configure
+++ configure
@@ -96,6 +96,7 @@ Configuration options:
--enable-x11grab enable X11 grabbing [no]
--disable-network disable network support [no]
--disable-mpegaudio-hp faster (but less accurate) MPEG audio decoding [no]
+ --disable-ac3enc-float faster (but less accurate) AC-3 audio encoding [no]
--enable-gray enable full grayscale support (slower color)
--disable-swscale-alpha disable alpha channel support in swscale
--disable-fastdiv disable table-based division
@@ -907,6 +908,7 @@ CONFIG_LIST="
memalign_hack
mlib
mpegaudio_hp
+ ac3enc_float
network
nonfree
pic
@@ -1496,6 +1498,8 @@ test_deps _encoder _decoder \
wmv1 \
wmv2 \
+ac3_test_deps="${ac3_test_deps} ac3enc_float rm_muxer rm_demuxer"
+
test_deps _muxer _demuxer \
aiff \
pcm_alaw=alaw \
@@ -1583,6 +1587,7 @@ enable ffplay
enable ffprobe
enable ffserver
enable mpegaudio_hp
+enable ac3enc_float
enable network
enable optimizations
enable protocols
diff --git libavcodec/ac3enc.c libavcodec/ac3enc.c
index 106cc05..919c51a 100644
--- libavcodec/ac3enc.c
+++ libavcodec/ac3enc.c
@@ -38,36 +38,12 @@
#include "ac3.h"
#include "audioconvert.h"
-//#define CONFIG_FLOAT 1
-
-#ifndef CONFIG_FLOAT
-#define CONFIG_FLOAT 0
-#endif
-
-#if CONFIG_FLOAT
-#include "fft.h"
-#endif
-
#define SCALE_FLOAT(a, bits) (lrintf(a * (float)(1 << (bits))))
-#if CONFIG_FLOAT
- typedef float SampleType;
- typedef float CoefType;
-# define FIX(a) (a)
-# define MULFUNC(a, b) ((a) * (b))
-# define FIX_SHIFT(a) (a)
-# define RSHIFT1(a) ((a) * 0.5f)
-# define SCALE_COEF(a) SCALE_FLOAT((a), 24)
-# define INPUT_SAMPLE_FMT SAMPLE_FMT_FLT
+#if CONFIG_AC3ENC_FLOAT
+#include "ac3enc_float.h"
#else
- typedef int16_t SampleType;
- typedef int32_t CoefType;
-# define FIX(a) (av_clip_int16(SCALE_FLOAT(a, 15)))
-# define MULFUNC MUL16
-# define FIX_SHIFT(a) ((a) >> 15)
-# define RSHIFT1(a) ((a) >> 1)
-# define SCALE_COEF(a) (a)
-# define INPUT_SAMPLE_FMT SAMPLE_FMT_S16
+#include "ac3enc_fixed.h"
#endif
typedef struct AC3EncOptions {
@@ -96,28 +72,6 @@ typedef struct AC3EncOptions {
/* encoding options */
} AC3EncOptions;
-#if !CONFIG_FLOAT
-typedef struct IComplex {
- SampleType re,im;
-} IComplex;
-#endif
-
-typedef struct AC3MDCTContext {
- const SampleType *window; ///< MDCT window function
- AVCodecContext *avctx; ///< parent context for av_log()
- int nbits; ///< log2(transform size)
-#if CONFIG_FLOAT
- FFTContext fft; ///< FFT Context for MDCT calculation
-#else
- SampleType *costab; ///< FFT cos table
- SampleType *sintab; ///< FFT sin table
- SampleType *xcos1; ///< MDCT cos table
- SampleType *xsin1; ///< MDCT sin table
- SampleType *rot_tmp; ///< temp buffer for pre-rotated samples
- IComplex *cplx_tmp; ///< temp buffer for complex pre-rotated samples
-#endif
-} AC3MDCTContext;
-
typedef struct AC3Block {
uint8_t **bap; ///< bap for each channel in this block
CoefType **mdct_coef; ///< MDCT coefficients for each channel in this block
@@ -278,291 +232,12 @@ static const AVClass class = { "ac3", av_default_item_name, options, LIBAVUTIL_V
*/
int exponent_group_tab[3][256];
-#if CONFIG_FLOAT
-static av_cold void mdct_end(AC3MDCTContext *mdct)
-{
- mdct->nbits = 0;
- ff_mdct_end(&mdct->fft);
- av_freep(&mdct->window);
-}
+#if CONFIG_AC3ENC_FLOAT
+#include "ac3enc_float.c"
#else
-static av_cold void mdct_end(AC3MDCTContext *mdct)
-{
- mdct->nbits = 0;
- av_freep(&mdct->costab);
- av_freep(&mdct->sintab);
- av_freep(&mdct->xcos1);
- av_freep(&mdct->xsin1);
- av_freep(&mdct->rot_tmp);
- av_freep(&mdct->cplx_tmp);
-}
+#include "ac3enc_fixed.c"
#endif
-#if !CONFIG_FLOAT
-static av_cold int fft_init(AC3MDCTContext *mdct, int ln)
-{
- int i, n, n2;
- float alpha;
-
- n = 1 << ln;
- n2 = n >> 1;
-
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->costab, n2 * sizeof(*mdct->costab),
- fft_alloc_fail);
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->sintab, n2 * sizeof(*mdct->sintab),
- fft_alloc_fail);
-
- for (i = 0; i < n2; i++) {
- alpha = 2 * M_PI * (float)i / (float)n;
- mdct->costab[i] = FIX(cos(alpha));
- mdct->sintab[i] = FIX(sin(alpha));
- }
-
- return 0;
-
-fft_alloc_fail:
- mdct_end(mdct);
- return AVERROR(ENOMEM);
-}
-#endif
-
-#if CONFIG_FLOAT
-static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
-{
- SampleType *window;
- int n = 1 << nbits;
- int n2 = (1 << mdct->nbits) >> 1;
-
- mdct->nbits = nbits;
-
- window = av_malloc(n2 * sizeof(*window));
- if (!window)
- return AVERROR(ENOMEM);
- ff_kbd_window_init(window, 5.0, n2);
- mdct->window = window;
-
- return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n);
-}
-#else
-static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
-{
- int ret;
- int n = 1 << nbits;
- int i, n2, n4;
-
- mdct->nbits = nbits;
-
- ret = fft_init(mdct, nbits - 2);
- if (ret)
- return ret;
-
- mdct->window = ff_ac3_window;
-
- n2 = n >> 1;
- n4 = n >> 2;
-
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xcos1, n4 * sizeof(*mdct->xcos1),
- mdct_alloc_fail);
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xsin1 , n4 * sizeof(*mdct->xsin1),
- mdct_alloc_fail);
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->rot_tmp, n * sizeof(*mdct->rot_tmp),
- mdct_alloc_fail);
- FF_ALLOC_OR_GOTO(mdct->avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp),
- mdct_alloc_fail);
-
- for (i = 0; i < n4; i++) {
- float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
- mdct->xcos1[i] = FIX(-cos(alpha));
- mdct->xsin1[i] = FIX(-sin(alpha));
- }
-
- return 0;
-
-mdct_alloc_fail:
- mdct_end(mdct);
- return AVERROR(ENOMEM);
-}
-#endif
-
-#if !CONFIG_FLOAT
-
-/* butter fly op */
-#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
-{\
- CoefType ax, ay, bx, by;\
- bx = pre1;\
- by = pim1;\
- ax = qre1;\
- ay = qim1;\
- pre = RSHIFT1(bx + ax);\
- pim = RSHIFT1(by + ay);\
- qre = RSHIFT1(bx - ax);\
- qim = RSHIFT1(by - ay);\
-}
-
-#define CMUL(pre, pim, are, aim, bre, bim) \
-{\
- pre = FIX_SHIFT(MULFUNC(are, bre) - MULFUNC(aim, bim));\
- pim = FIX_SHIFT(MULFUNC(are, bim) + MULFUNC(bre, aim));\
-}
-
-
-/* do a 2^n point complex fft on 2^ln points. */
-static void calc_fft(AC3MDCTContext *mdct, IComplex *z, int ln)
-{
- int j, l, np, np2;
- int nblocks, nloops;
- register IComplex *p,*q;
- CoefType tmp_re, tmp_im;
-
- np = 1 << ln;
-
- /* reverse */
- for(j = 0; j < np; j++) {
- int k = av_reverse[j] >> (8 - ln);
- if (k < j)
- FFSWAP(IComplex, z[k], z[j]);
- }
-
- /* pass 0 */
-
- p = &z[0];
- j = np >> 1;
- do {
- BF(p[0].re, p[0].im, p[1].re, p[1].im,
- p[0].re, p[0].im, p[1].re, p[1].im);
- p += 2;
- } while (--j);
-
- /* pass 1 */
-
- p = &z[0];
- j = np >> 2;
- do {
- BF(p[0].re, p[0].im, p[2].re, p[2].im,
- p[0].re, p[0].im, p[2].re, p[2].im);
- BF(p[1].re, p[1].im, p[3].re, p[3].im,
- p[1].re, p[1].im, p[3].im, -p[3].re);
- p += 4;
- } while (--j);
-
- /* pass 2 .. ln-1 */
-
- nblocks = np >> 3;
- nloops = 1 << 2;
- np2 = np >> 1;
- do {
- p = z;
- q = z + nloops;
- for (j = 0; j < nblocks; j++) {
- BF(p->re, p->im, q->re, q->im,
- p->re, p->im, q->re, q->im);
-
- p++;
- q++;
- for (l = nblocks; l < np2; l += nblocks) {
- CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
- BF(p->re, p->im, q->re, q->im,
- p->re, p->im, tmp_re, tmp_im);
- p++;
- q++;
- }
- p += nloops;
- q += nloops;
- }
- nblocks = nblocks >> 1;
- nloops = nloops << 1;
- } while (nblocks != 0);
-}
-
-/* do a 512 point mdct */
-static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
-{
- int i;
- CoefType re, im;
- int n, n2, n4;
- SampleType *rot = mdct->rot_tmp;
- IComplex *x = mdct->cplx_tmp;
-
- n = 1 << mdct->nbits;
- n2 = n >> 1;
- n4 = n >> 2;
-
- /* shift to simplify computations */
- for (i = 0; i < n4; i++)
- rot[i] = -in[i+3*n4];
- memcpy(rot+n4, in, 3*n4 * sizeof(*in));
-
- /* pre rotation */
- for (i = 0; i < n4; i++) {
- re = RSHIFT1( ((CoefType)rot[ 2*i] - (CoefType)rot[ n-1-2*i]));
- im = RSHIFT1(-((CoefType)rot[n2+2*i] - (CoefType)rot[n2-1-2*i]));
- CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
- }
-
- calc_fft(mdct, x, mdct->nbits - 2);
-
- /* post rotation */
- 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]);
- }
-}
-#else /* CONFIG_FLOAT */
-static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
-{
- ff_mdct_calc(&mdct->fft, out, in);
-}
-#endif /* !CONFIG_FLOAT */
-
-#if !CONFIG_FLOAT
-/* compute log2(max(abs(tab[]))) */
-static int log2_tab(int16_t *tab, int n)
-{
- int i, v;
-
- v = 0;
- for (i = 0; i < n; i++)
- v |= abs(tab[i]);
- return av_log2(v);
-}
-
-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.
- *
- * @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;
-}
-#else /* CONFIG_FLOAT */
-static int normalize_samples(AC3EncodeContext *s)
-{
- return 0;
-}
-#endif /* !CONFIG_FLOAT */
-
static void apply_window(SampleType *output, const SampleType *input,
const SampleType *window, int n)
{
@@ -1935,7 +1610,7 @@ static int AC3_encode_frame(AVCodecContext *avctx,
return s->frame_size;
}
-#if !CONFIG_FLOAT
+#if !CONFIG_AC3ENC_FLOAT
#ifdef TEST
/*************************************************************************/
/* TEST */
@@ -2058,7 +1733,7 @@ int main(void)
return 0;
}
#endif /* TEST */
-#endif /* !CONFIG_FLOAT */
+#endif /* !CONFIG_AC3ENC_FLOAT */
AVCodec ac3_encoder = {
"ac3",
diff --git libavcodec/ac3enc_fixed.c libavcodec/ac3enc_fixed.c
new file mode 100644
index 0000000..6d0cd1b
--- /dev/null
+++ libavcodec/ac3enc_fixed.c
@@ -0,0 +1,267 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder fixed-point functions.
+ */
+
+static av_cold void mdct_end(AC3MDCTContext *mdct)
+{
+ mdct->nbits = 0;
+ av_freep(&mdct->costab);
+ av_freep(&mdct->sintab);
+ av_freep(&mdct->xcos1);
+ av_freep(&mdct->xsin1);
+ av_freep(&mdct->rot_tmp);
+ av_freep(&mdct->cplx_tmp);
+}
+
+static av_cold int fft_init(AC3MDCTContext *mdct, int ln)
+{
+ int i, n, n2;
+ float alpha;
+
+ n = 1 << ln;
+ n2 = n >> 1;
+
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->costab, n2 * sizeof(*mdct->costab),
+ fft_alloc_fail);
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->sintab, n2 * sizeof(*mdct->sintab),
+ fft_alloc_fail);
+
+ for (i = 0; i < n2; i++) {
+ alpha = 2 * M_PI * (float)i / (float)n;
+ mdct->costab[i] = FIX(cos(alpha));
+ mdct->sintab[i] = FIX(sin(alpha));
+ }
+
+ return 0;
+
+fft_alloc_fail:
+ mdct_end(mdct);
+ return AVERROR(ENOMEM);
+}
+
+static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
+{
+ int ret;
+ int n = 1 << nbits;
+ int i, n2, n4;
+
+ mdct->nbits = nbits;
+
+ ret = fft_init(mdct, nbits - 2);
+ if (ret)
+ return ret;
+
+ mdct->window = ff_ac3_window;
+
+ n2 = n >> 1;
+ n4 = n >> 2;
+
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xcos1, n4 * sizeof(*mdct->xcos1),
+ mdct_alloc_fail);
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->xsin1 , n4 * sizeof(*mdct->xsin1),
+ mdct_alloc_fail);
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->rot_tmp, n * sizeof(*mdct->rot_tmp),
+ mdct_alloc_fail);
+ FF_ALLOC_OR_GOTO(mdct->avctx, mdct->cplx_tmp, n4 * sizeof(*mdct->cplx_tmp),
+ mdct_alloc_fail);
+
+ for (i = 0; i < n4; i++) {
+ float alpha = 2.0 * M_PI * (i + 1.0 / 8.0) / n;
+ mdct->xcos1[i] = FIX(-cos(alpha));
+ mdct->xsin1[i] = FIX(-sin(alpha));
+ }
+
+ return 0;
+
+mdct_alloc_fail:
+ mdct_end(mdct);
+ return AVERROR(ENOMEM);
+}
+
+/* butter fly op */
+#define BF(pre, pim, qre, qim, pre1, pim1, qre1, qim1) \
+{\
+ CoefType ax, ay, bx, by;\
+ bx = pre1;\
+ by = pim1;\
+ ax = qre1;\
+ ay = qim1;\
+ pre = RSHIFT1(bx + ax);\
+ pim = RSHIFT1(by + ay);\
+ qre = RSHIFT1(bx - ax);\
+ qim = RSHIFT1(by - ay);\
+}
+
+#define CMUL(pre, pim, are, aim, bre, bim) \
+{\
+ pre = FIX_SHIFT(MULFUNC(are, bre) - MULFUNC(aim, bim));\
+ pim = FIX_SHIFT(MULFUNC(are, bim) + MULFUNC(bre, aim));\
+}
+
+
+/* do a 2^n point complex fft on 2^ln points. */
+static void calc_fft(AC3MDCTContext *mdct, IComplex *z, int ln)
+{
+ int j, l, np, np2;
+ int nblocks, nloops;
+ register IComplex *p,*q;
+ CoefType tmp_re, tmp_im;
+
+ np = 1 << ln;
+
+ /* reverse */
+ for(j = 0; j < np; j++) {
+ int k = av_reverse[j] >> (8 - ln);
+ if (k < j)
+ FFSWAP(IComplex, z[k], z[j]);
+ }
+
+ /* pass 0 */
+
+ p = &z[0];
+ j = np >> 1;
+ do {
+ BF(p[0].re, p[0].im, p[1].re, p[1].im,
+ p[0].re, p[0].im, p[1].re, p[1].im);
+ p += 2;
+ } while (--j);
+
+ /* pass 1 */
+
+ p = &z[0];
+ j = np >> 2;
+ do {
+ BF(p[0].re, p[0].im, p[2].re, p[2].im,
+ p[0].re, p[0].im, p[2].re, p[2].im);
+ BF(p[1].re, p[1].im, p[3].re, p[3].im,
+ p[1].re, p[1].im, p[3].im, -p[3].re);
+ p += 4;
+ } while (--j);
+
+ /* pass 2 .. ln-1 */
+
+ nblocks = np >> 3;
+ nloops = 1 << 2;
+ np2 = np >> 1;
+ do {
+ p = z;
+ q = z + nloops;
+ for (j = 0; j < nblocks; j++) {
+ BF(p->re, p->im, q->re, q->im,
+ p->re, p->im, q->re, q->im);
+
+ p++;
+ q++;
+ for (l = nblocks; l < np2; l += nblocks) {
+ CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im);
+ BF(p->re, p->im, q->re, q->im,
+ p->re, p->im, tmp_re, tmp_im);
+ p++;
+ q++;
+ }
+ p += nloops;
+ q += nloops;
+ }
+ nblocks = nblocks >> 1;
+ nloops = nloops << 1;
+ } while (nblocks != 0);
+}
+
+/* do a 512 point mdct */
+static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
+{
+ int i;
+ CoefType re, im;
+ int n, n2, n4;
+ SampleType *rot = mdct->rot_tmp;
+ IComplex *x = mdct->cplx_tmp;
+
+ n = 1 << mdct->nbits;
+ n2 = n >> 1;
+ n4 = n >> 2;
+
+ /* shift to simplify computations */
+ for (i = 0; i < n4; i++)
+ rot[i] = -in[i+3*n4];
+ memcpy(rot+n4, in, 3*n4 * sizeof(*in));
+
+ /* pre rotation */
+ for (i = 0; i < n4; i++) {
+ re = RSHIFT1( ((CoefType)rot[ 2*i] - (CoefType)rot[ n-1-2*i]));
+ im = RSHIFT1(-((CoefType)rot[n2+2*i] - (CoefType)rot[n2-1-2*i]));
+ CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]);
+ }
+
+ calc_fft(mdct, x, mdct->nbits - 2);
+
+ /* post rotation */
+ 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]);
+ }
+}
+
+/* compute log2(max(abs(tab[]))) */
+static int log2_tab(int16_t *tab, int n)
+{
+ int i, v;
+
+ v = 0;
+ for (i = 0; i < n; i++)
+ v |= abs(tab[i]);
+ return av_log2(v);
+}
+
+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.
+ *
+ * @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;
+}
diff --git libavcodec/ac3enc_fixed.h libavcodec/ac3enc_fixed.h
new file mode 100644
index 0000000..0d1fc26
--- /dev/null
+++ libavcodec/ac3enc_fixed.h
@@ -0,0 +1,57 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder fixed-point header.
+ */
+
+#ifndef AVCODEC_AC3ENC_FIXED_H
+#define AVCODEC_AC3ENC_FIXED_H
+
+typedef int16_t SampleType;
+typedef int32_t CoefType;
+#define FIX(a) (av_clip_int16(SCALE_FLOAT(a, 15)))
+#define MULFUNC MUL16
+#define FIX_SHIFT(a) ((a) >> 15)
+#define RSHIFT1(a) ((a) >> 1)
+#define SCALE_COEF(a) (a)
+#define INPUT_SAMPLE_FMT SAMPLE_FMT_S16
+
+typedef struct IComplex {
+ SampleType re,im;
+} IComplex;
+
+typedef struct AC3MDCTContext {
+ const SampleType *window; ///< MDCT window function
+ AVCodecContext *avctx; ///< parent context for av_log()
+ int nbits; ///< log2(transform size)
+ SampleType *costab; ///< FFT cos table
+ SampleType *sintab; ///< FFT sin table
+ SampleType *xcos1; ///< MDCT cos table
+ SampleType *xsin1; ///< MDCT sin table
+ SampleType *rot_tmp; ///< temp buffer for pre-rotated samples
+ IComplex *cplx_tmp; ///< temp buffer for complex pre-rotated samples
+} AC3MDCTContext;
+
+#endif /* AVCODEC_AC3ENC_FIXED_H */
diff --git libavcodec/ac3enc_float.c libavcodec/ac3enc_float.c
new file mode 100644
index 0000000..e08310e
--- /dev/null
+++ libavcodec/ac3enc_float.c
@@ -0,0 +1,61 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder floating-point functions.
+ */
+
+static av_cold void mdct_end(AC3MDCTContext *mdct)
+{
+ mdct->nbits = 0;
+ ff_mdct_end(&mdct->fft);
+ av_freep(&mdct->window);
+}
+
+static av_cold int mdct_init(AC3MDCTContext *mdct, int nbits)
+{
+ SampleType *window;
+ int n = 1 << nbits;
+ int n2 = n >> 1;
+
+ mdct->nbits = nbits;
+
+ window = av_malloc(n2 * sizeof(*window));
+ if (!window)
+ return AVERROR(ENOMEM);
+ ff_kbd_window_init(window, 5.0, n2);
+ mdct->window = window;
+
+ return ff_mdct_init(&mdct->fft, nbits, 0, -2.0 / n);
+}
+
+static void calc_mdct(AC3MDCTContext *mdct, CoefType *out, SampleType *in)
+{
+ ff_mdct_calc(&mdct->fft, out, in);
+}
+
+static int normalize_samples(AC3EncodeContext *s)
+{
+ return 0;
+}
diff --git libavcodec/ac3enc_float.h libavcodec/ac3enc_float.h
new file mode 100644
index 0000000..c42044f
--- /dev/null
+++ libavcodec/ac3enc_float.h
@@ -0,0 +1,50 @@
+/*
+ * The simplest AC-3 encoder
+ * Copyright (c) 2000 Fabrice Bellard
+ * Copyright (c) 2006-2010 Justin Ruggles <[email protected]>
+ * Copyright (c) 2006-2010 Prakash Punnoor <[email protected]>
+ *
+ * This file is part of FFmpeg.
+ *
+ * FFmpeg 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,
+ * 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
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * @file
+ * AC-3 encoder floating-point header.
+ */
+
+#ifndef AVCODEC_AC3ENC_FLOAT_H
+#define AVCODEC_AC3ENC_FLOAT_H
+
+#include "fft.h"
+
+typedef float SampleType;
+typedef float CoefType;
+#define FIX(a) (a)
+#define MULFUNC(a, b) ((a) * (b))
+#define FIX_SHIFT(a) (a)
+#define RSHIFT1(a) ((a) * 0.5f)
+#define SCALE_COEF(a) SCALE_FLOAT((a), 24)
+#define INPUT_SAMPLE_FMT SAMPLE_FMT_FLT
+
+typedef struct AC3MDCTContext {
+ const SampleType *window; ///< MDCT window function
+ AVCodecContext *avctx; ///< parent context for av_log()
+ int nbits; ///< log2(transform size)
+ FFTContext fft; ///< FFT Context for MDCT calculation
+} AC3MDCTContext;
+
+#endif /* AVCODEC_AC3ENC_FLOAT_H */
diff --git tests/codec-regression.sh tests/codec-regression.sh
index 2a2ca1c..0fe1df4 100755
--- tests/codec-regression.sh
+++ tests/codec-regression.sh
@@ -271,9 +271,8 @@ fi
if [ -n "$do_ac3" ] ; then
do_audio_encoding ac3.rm "" -vn
-# binaries configured with --disable-sse decode ac3 differently
-#do_audio_decoding
-#$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile
+do_ffmpeg_nomd5 $pcm_dst -i $target_path/$file -f wav
+$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile
fi
if [ -n "$do_g726" ] ; then
diff --git tests/ref/acodec/ac3 tests/ref/acodec/ac3
index 32f47e0..0b750ca 100644
--- tests/ref/acodec/ac3
+++ tests/ref/acodec/ac3
@@ -1,2 +1,4 @@
-464093173530736050e338caf152044c *./tests/data/acodec/ac3.rm
+7a367bc8be390924baf879fe5d9eac23 *./tests/data/acodec/ac3.rm
98751 ./tests/data/acodec/ac3.rm
+stddev:10491.51 PSNR: 15.91 MAXDIFF:65534 bytes: 1062912/ 1058400
+stddev: 4626.53 PSNR: 23.02 MAXDIFF:62579 bytes: 1061888/ 1058400
_______________________________________________
FFmpeg-soc mailing list
[email protected]
https://lists.mplayerhq.hu/mailman/listinfo/ffmpeg-soc