Implementation of AC3 fixed point decoder
Hello, Resending patches that are implementing AC3 fixed point decoder. Requested changes are applied: _fixed removed from vector_fmul_vindow_ functions names change in Changelog placed under <next> name for the decoder changed; using the same name as the encoder now Patches made by Michael that split the patch "libavcodec: Implementation of AC3 fixedpoint decoder" and fixe a few issues are also resubmited, so they are rebased to the newest ffmpeg code and entire patchset is in one place. -Nedeljko
From: Nedeljko Babic <nbabic@mips.com> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavutil/Makefile | 1 + libavutil/fixed_dsp.c | 98 ++++++++++++++++++++++++++++++++++ libavutil/fixed_dsp.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 libavutil/fixed_dsp.c create mode 100644 libavutil/fixed_dsp.h diff --git a/libavutil/Makefile b/libavutil/Makefile index 2fe3e15..a90347c 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -89,6 +89,7 @@ OBJS = adler32.o \ file.o \ file_open.o \ float_dsp.o \ + fixed_dsp.o \ frame.o \ hash.o \ hmac.o \ diff --git a/libavutil/fixed_dsp.c b/libavutil/fixed_dsp.c new file mode 100644 index 0000000..6aceaac --- /dev/null +++ b/libavutil/fixed_dsp.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * 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 + */ + +#include "fixed_dsp.h" + +static void vector_fmul_window_fixed_scaled_c(int16_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len, uint8_t bits) +{ + int32_t s0, s1, wi, wj, i,j, round; + + dst += len; + win += len; + src0+= len; + round = bits? 1 << (bits-1) : 0; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = av_clip_int16_c(((((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31) + round) >> bits); + dst[j] = av_clip_int16_c(((((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31) + round) >> bits); + } +} + +static void vector_fmul_window_fixed_c(int32_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len) +{ + int32_t s0, s1, wi, wj, i, j; + + dst += len; + win += len; + src0+= len; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = ((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31; + dst[j] = ((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31; + } +} + +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int bit_exact) +{ + AVFixedDSPContext * fdsp = (AVFixedDSPContext*)av_malloc(sizeof(AVFixedDSPContext)); + fdsp->vector_fmul_window_scaled = vector_fmul_window_fixed_scaled_c; + fdsp->vector_fmul_window = vector_fmul_window_fixed_c; + + return fdsp; +} diff --git a/libavutil/fixed_dsp.h b/libavutil/fixed_dsp.h new file mode 100644 index 0000000..ff6f365 --- /dev/null +++ b/libavutil/fixed_dsp.h @@ -0,0 +1,144 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * 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 + */ + +#ifndef AVUTIL_FIXED_DSP_H +#define AVUTIL_FIXED_DSP_H + +#include <stdint.h> +#include "attributes.h" +#include "common.h" +#include "libavcodec/mathops.h" + +typedef struct AVFixedDSPContext { + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 16-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + * @param bits scaling parameter + * + */ + void (*vector_fmul_window_scaled)(int16_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len, uint8_t bits); + + /** + * Overlap/add with window function. + * Used primarily by MDCT-based audio codecs. + * Source and destination vectors must overlap exactly or not at all. + * + * @param dst result vector + * constraints: 32-byte aligned + * @param src0 first source vector + * constraints: 16-byte aligned + * @param src1 second source vector + * constraints: 16-byte aligned + * @param win half-window vector + * constraints: 16-byte aligned + * @param len length of vector + * constraints: multiple of 4 + */ + void (*vector_fmul_window)(int32_t *dst, const int32_t *src0, const int32_t *src1, const int32_t *win, int len); + +} AVFixedDSPContext; + +/** + * Allocate and initialize a fixed DSP context. + * note: should be freed with a av_free call when no longer needed. + * + * @param strict setting to non-zero avoids using functions which may not be IEEE-754 compliant + */ +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int strict); + +/** + * Calculate the square root + * + * @param x input fixed point number + * + * @param bits format of fixed point number (32 - bits).bits + * + * note: input is normalized to (0, 1) fixed point value + */ + +static av_always_inline int fixed_sqrt(int x, int bits) +{ + int retval, bit_mask, guess, square, i; + int64_t accu; + int shift1 = 30 - bits; + int shift2 = bits - 15; + + if (shift1 > 0) retval = ff_sqrt(x << shift1); + else retval = ff_sqrt(x >> -shift1); + + if (shift2 > 0) { + retval = retval << shift2; + bit_mask = (1 << (shift2 - 1)); + + for (i=0; i<shift2; i++){ + guess = retval + bit_mask; + accu = (int64_t)guess * guess; + square = (int)((accu + bit_mask) >> bits); + if (x >= square) + retval += bit_mask; + bit_mask >>= 1; + } + + } + else retval >>= (-shift2); + + return retval; +} + +#endif /* AVUTIL_FIXED_DSP_H */ diff --git a/libavutil/version.h b/libavutil/version.h index 644f157..73bdfab 100644 --- a/libavutil/version.h +++ b/libavutil/version.h @@ -56,7 +56,7 @@ */ #define LIBAVUTIL_VERSION_MAJOR 52 -#define LIBAVUTIL_VERSION_MINOR 70 +#define LIBAVUTIL_VERSION_MINOR 71 #define LIBAVUTIL_VERSION_MICRO 100 #define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \ -- 1.8.2.1
On Tue, Apr 01, 2014 at 04:31:07PM +0200, Nedeljko Babic wrote:
From: Nedeljko Babic <nbabic@mips.com>
Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavutil/Makefile | 1 + libavutil/fixed_dsp.c | 98 ++++++++++++++++++++++++++++++++++ libavutil/fixed_dsp.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 libavutil/fixed_dsp.c create mode 100644 libavutil/fixed_dsp.h
applied thanks [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Rewriting code that is poorly written but fully understood is good. Rewriting code that one doesnt understand is a sign that one is less smart then the original author, trying to rewrite it will not make it better.
On 01/04/14 11:31 AM, Nedeljko Babic wrote:
From: Nedeljko Babic <nbabic@mips.com>
Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavutil/Makefile | 1 + libavutil/fixed_dsp.c | 98 ++++++++++++++++++++++++++++++++++ libavutil/fixed_dsp.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 libavutil/fixed_dsp.c create mode 100644 libavutil/fixed_dsp.h
diff --git a/libavutil/Makefile b/libavutil/Makefile index 2fe3e15..a90347c 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -89,6 +89,7 @@ OBJS = adler32.o \ file.o \ file_open.o \ float_dsp.o \ + fixed_dsp.o \ frame.o \ hash.o \ hmac.o \ diff --git a/libavutil/fixed_dsp.c b/libavutil/fixed_dsp.c new file mode 100644 index 0000000..6aceaac --- /dev/null +++ b/libavutil/fixed_dsp.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * 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 + */ + +#include "fixed_dsp.h" + +static void vector_fmul_window_fixed_scaled_c(int16_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len, uint8_t bits) +{ + int32_t s0, s1, wi, wj, i,j, round; + + dst += len; + win += len; + src0+= len; + round = bits? 1 << (bits-1) : 0; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = av_clip_int16_c(((((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31) + round) >> bits); + dst[j] = av_clip_int16_c(((((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31) + round) >> bits); + } +} + +static void vector_fmul_window_fixed_c(int32_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len) +{ + int32_t s0, s1, wi, wj, i, j; + + dst += len; + win += len; + src0+= len; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = ((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31; + dst[j] = ((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31; + } +} + +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int bit_exact) +{ + AVFixedDSPContext * fdsp = (AVFixedDSPContext*)av_malloc(sizeof(AVFixedDSPContext)); + fdsp->vector_fmul_window_scaled = vector_fmul_window_fixed_scaled_c; + fdsp->vector_fmul_window = vector_fmul_window_fixed_c; + + return fdsp;
I didn't catch this before, but why allocate the struct during init? Why not doing it the same way as AVFloatDSPContext? Having the fixed and float versions so different is weird. And having to call av_free() is annoying. Can this be changed at this point? It's been in the tree for a few hours so it shouldn't be a problem.
On Wed, Apr 02, 2014 at 12:48:53AM -0300, James Almer wrote:
On 01/04/14 11:31 AM, Nedeljko Babic wrote:
From: Nedeljko Babic <nbabic@mips.com>
Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavutil/Makefile | 1 + libavutil/fixed_dsp.c | 98 ++++++++++++++++++++++++++++++++++ libavutil/fixed_dsp.h | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++ libavutil/version.h | 2 +- 4 files changed, 244 insertions(+), 1 deletion(-) create mode 100644 libavutil/fixed_dsp.c create mode 100644 libavutil/fixed_dsp.h
diff --git a/libavutil/Makefile b/libavutil/Makefile index 2fe3e15..a90347c 100644 --- a/libavutil/Makefile +++ b/libavutil/Makefile @@ -89,6 +89,7 @@ OBJS = adler32.o \ file.o \ file_open.o \ float_dsp.o \ + fixed_dsp.o \ frame.o \ hash.o \ hmac.o \ diff --git a/libavutil/fixed_dsp.c b/libavutil/fixed_dsp.c new file mode 100644 index 0000000..6aceaac --- /dev/null +++ b/libavutil/fixed_dsp.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Nedeljko Babic (nbabic@mips.com) + * + * 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 + */ + +#include "fixed_dsp.h" + +static void vector_fmul_window_fixed_scaled_c(int16_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len, uint8_t bits) +{ + int32_t s0, s1, wi, wj, i,j, round; + + dst += len; + win += len; + src0+= len; + round = bits? 1 << (bits-1) : 0; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = av_clip_int16_c(((((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31) + round) >> bits); + dst[j] = av_clip_int16_c(((((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31) + round) >> bits); + } +} + +static void vector_fmul_window_fixed_c(int32_t *dst, const int32_t *src0, + const int32_t *src1, const int32_t *win, + int len) +{ + int32_t s0, s1, wi, wj, i, j; + + dst += len; + win += len; + src0+= len; + + for (i=-len, j=len-1; i<0; i++, j--) { + s0 = src0[i]; + s1 = src1[j]; + wi = win[i]; + wj = win[j]; + dst[i] = ((int64_t)s0*wj - (int64_t)s1*wi + 0x40000000) >> 31; + dst[j] = ((int64_t)s0*wi + (int64_t)s1*wj + 0x40000000) >> 31; + } +} + +AVFixedDSPContext * avpriv_alloc_fixed_dsp(int bit_exact) +{ + AVFixedDSPContext * fdsp = (AVFixedDSPContext*)av_malloc(sizeof(AVFixedDSPContext)); + fdsp->vector_fmul_window_scaled = vector_fmul_window_fixed_scaled_c; + fdsp->vector_fmul_window = vector_fmul_window_fixed_c; + + return fdsp;
I didn't catch this before, but why allocate the struct during init? Why not doing it the same way as AVFloatDSPContext? Having the fixed and float versions so different is weird. And having to call av_free() is annoying.
if theres no alloc, then any addition to the structure requires a soname / major ABI bump the float dsp is what is broken [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB While the State exists there can be no freedom; when there is freedom there will be no State. -- Vladimir Lenin
From: Nedeljko Babic <nbabic@mips.com> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- Changelog | 1 + configure | 1 + doc/general.texi | 2 +- libavcodec/Makefile | 3 +- libavcodec/ac3.h | 46 +++++++++++ libavcodec/ac3dec.c | 197 +++++++++++++++++++++++++--------------------- libavcodec/ac3dec.h | 33 ++++---- libavcodec/ac3dec_fixed.c | 176 +++++++++++++++++++++++++++++++++++++++++ libavcodec/ac3dec_float.c | 89 +++++++++++++++++++++ libavcodec/ac3dsp.c | 26 ++++++ libavcodec/ac3dsp.h | 3 + libavcodec/allcodecs.c | 2 +- libavcodec/kbdwin.c | 10 +++ libavcodec/kbdwin.h | 1 + libavcodec/version.h | 2 +- 15 files changed, 483 insertions(+), 109 deletions(-) create mode 100644 libavcodec/ac3dec_fixed.c create mode 100644 libavcodec/ac3dec_float.c diff --git a/Changelog b/Changelog index 0e38ec8..b8147c9 100644 --- a/Changelog +++ b/Changelog @@ -2,6 +2,7 @@ Entries are sorted chronologically from oldest to youngest within each release, releases are sorted from youngest to oldest. version <next>: +- added AC3 fixed-point decoding - shuffleplanes filter - subfile protocol - Phantom Cine demuxer diff --git a/configure b/configure index b82891c..848dc7e 100755 --- a/configure +++ b/configure @@ -1951,6 +1951,7 @@ aac_decoder_select="mdct sinewin" aac_encoder_select="audio_frame_queue mdct sinewin" aac_latm_decoder_select="aac_decoder aac_latm_parser" ac3_decoder_select="mdct ac3dsp ac3_parser dsputil" +ac3_fixed_decoder_select="mdct ac3dsp ac3_parser dsputil" ac3_encoder_select="mdct ac3dsp dsputil" ac3_fixed_encoder_select="mdct ac3dsp dsputil" aic_decoder_select="dsputil golomb" diff --git a/doc/general.texi b/doc/general.texi index e9087df..9f17d48 100644 --- a/doc/general.texi +++ b/doc/general.texi @@ -820,7 +820,7 @@ following image formats are supported: @tab encoding supported through external library libaacplus @item AAC @tab E @tab X @tab encoding supported through external library libfaac and libvo-aacenc -@item AC-3 @tab IX @tab X +@item AC-3 @tab IX @tab IX @item ADPCM 4X Movie @tab @tab X @item ADPCM CDROM XA @tab @tab X @item ADPCM Creative Technology @tab @tab X diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 70a6e25..f68371a 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -94,7 +94,8 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ psymodel.o iirfilter.o \ mpeg4audio.o kbdwin.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o -OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o kbdwin.o +OBJS-$(CONFIG_AC3_DECODER) += ac3dec_float.o ac3dec_data.o ac3.o kbdwin.o +OBJS-$(CONFIG_AC3_FIXED_DECODER) += ac3dec_fixed.o ac3dec_data.o ac3.o kbdwin.o OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3enc.o ac3tab.o \ ac3.o kbdwin.o OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3enc.o ac3tab.o ac3.o diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index 0cc9e2c..ac3936d 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -51,6 +51,52 @@ #define EXP_D25 2 #define EXP_D45 3 +#ifndef CONFIG_AC3_FIXED +#define CONFIG_AC3_FIXED 0 +#endif + +#if CONFIG_AC3_FIXED + +#define FFT_FLOAT 0 + +#define FIXR(a) ((int)((a) * 0 + 0.5)) +#define FIXR12(a) ((int)((a) * 4096 + 0.5)) +#define FIXR15(a) ((int)((a) * 32768 + 0.5)) +#define ROUND15(x) ((x) + 16384) >> 15 + +#define AC3_RENAME(x) x ## _fixed +#define AC3_NORM(norm) (1<<24)/(norm) +#define AC3_MUL(a,b) ((((int64_t) (a)) * (b))>>12) +#define AC3_RANGE(x) (x) +#define AC3_DYNAMIC_RANGE(x) (x) +#define AC3_SPX_BLEND(x) (x) +#define AC3_DYNAMIC_RANGE1 0 + +#define INTFLOAT int +#define SHORTFLOAT int16_t + +#else /* CONFIG_AC3_FIXED */ + +#define FIXR(x) ((float)(x)) +#define FIXR12(x) ((float)(x)) +#define FIXR15(x) ((float)(x)) +#define ROUND15(x) (x) + +#define AC3_RENAME(x) x +#define AC3_NORM(norm) (1.0f/(norm)) +#define AC3_MUL(a,b) ((a) * (b)) +#define AC3_RANGE(x) (dynamic_range_tab[(x)]) +#define AC3_DYNAMIC_RANGE(x) (powf(x, s->drc_scale)) +#define AC3_SPX_BLEND(x) (x)* (1.0f/32) +#define AC3_DYNAMIC_RANGE1 1.0f + +#define INTFLOAT float +#define SHORTFLOAT float + +#endif /* CONFIG_AC3_FIXED */ + +#define AC3_LEVEL(x) ROUND15((x) * FIXR15(0.7071067811865476)) + /* pre-defined gain values */ #define LEVEL_PLUS_3DB 1.4142135623730950 #define LEVEL_PLUS_1POINT5DB 1.1892071150027209 diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 3a6a7ad..1d97df9 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -179,14 +179,23 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) ac3_tables_init(); ff_mdct_init(&s->imdct_256, 8, 1, 1.0); ff_mdct_init(&s->imdct_512, 9, 1, 1.0); - ff_kbd_window_init(s->window, 5.0, 256); + AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256); ff_dsputil_init(&s->dsp, avctx); + +#if (CONFIG_AC3_FIXED) + s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & CODEC_FLAG_BITEXACT); +#else avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); +#endif + ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT); ff_fmt_convert_init(&s->fmt_conv, avctx); av_lfg_init(&s->dith_state, 0); - avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; + if (CONFIG_AC3_FIXED) + avctx->sample_fmt = AV_SAMPLE_FMT_S16P; + else + avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; /* allow downmixing to stereo or mono */ #if FF_API_REQUEST_CHANNELS @@ -345,40 +354,45 @@ static void set_downmix_coeffs(AC3DecodeContext *s) float cmix = gain_levels[s-> center_mix_level]; float smix = gain_levels[s->surround_mix_level]; float norm0, norm1; + float downmix_coeffs[AC3_MAX_CHANNELS][2]; for (i = 0; i < s->fbw_channels; i++) { - s->downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; - s->downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; + downmix_coeffs[i][0] = gain_levels[ac3_default_coeffs[s->channel_mode][i][0]]; + downmix_coeffs[i][1] = gain_levels[ac3_default_coeffs[s->channel_mode][i][1]]; } if (s->channel_mode > 1 && s->channel_mode & 1) { - s->downmix_coeffs[1][0] = s->downmix_coeffs[1][1] = cmix; + downmix_coeffs[1][0] = downmix_coeffs[1][1] = cmix; } if (s->channel_mode == AC3_CHMODE_2F1R || s->channel_mode == AC3_CHMODE_3F1R) { int nf = s->channel_mode - 2; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB; + downmix_coeffs[nf][0] = downmix_coeffs[nf][1] = smix * LEVEL_MINUS_3DB; } if (s->channel_mode == AC3_CHMODE_2F2R || s->channel_mode == AC3_CHMODE_3F2R) { int nf = s->channel_mode - 4; - s->downmix_coeffs[nf][0] = s->downmix_coeffs[nf+1][1] = smix; + downmix_coeffs[nf][0] = downmix_coeffs[nf+1][1] = smix; } /* renormalize */ norm0 = norm1 = 0.0; for (i = 0; i < s->fbw_channels; i++) { - norm0 += s->downmix_coeffs[i][0]; - norm1 += s->downmix_coeffs[i][1]; + norm0 += downmix_coeffs[i][0]; + norm1 += downmix_coeffs[i][1]; } norm0 = 1.0f / norm0; norm1 = 1.0f / norm1; for (i = 0; i < s->fbw_channels; i++) { - s->downmix_coeffs[i][0] *= norm0; - s->downmix_coeffs[i][1] *= norm1; + downmix_coeffs[i][0] *= norm0; + downmix_coeffs[i][1] *= norm1; } if (s->output_mode == AC3_CHMODE_MONO) { for (i = 0; i < s->fbw_channels; i++) - s->downmix_coeffs[i][0] = (s->downmix_coeffs[i][0] + - s->downmix_coeffs[i][1]) * LEVEL_MINUS_3DB; + downmix_coeffs[i][0] = (downmix_coeffs[i][0] + + downmix_coeffs[i][1]) * LEVEL_MINUS_3DB; + } + for (i = 0; i < s->fbw_channels; i++) { + s->downmix_coeffs[i][0] = FIXR12(downmix_coeffs[i][0]); + s->downmix_coeffs[i][1] = FIXR12(downmix_coeffs[i][1]); } } @@ -646,20 +660,30 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) for (ch = 1; ch <= channels; ch++) { if (s->block_switch[ch]) { int i; - float *x = s->tmp_output + 128; + FFTSample *x = s->tmp_output + 128; for (i = 0; i < 128; i++) x[i] = s->transform_coeffs[ch][2 * i]; s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x); +#if CONFIG_AC3_FIXED + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], + s->tmp_output, s->window, 128, 8); +#else s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1], s->tmp_output, s->window, 128); +#endif for (i = 0; i < 128; i++) x[i] = s->transform_coeffs[ch][2 * i + 1]; s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x); } else { s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]); +#if CONFIG_AC3_FIXED + s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], + s->tmp_output, s->window, 128, 8); +#else s->fdsp.vector_fmul_window(s->outptr[ch - 1], s->delay[ch - 1], s->tmp_output, s->window, 128); - memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(float)); +#endif + memcpy(s->delay[ch - 1], s->tmp_output + 128, 128 * sizeof(FFTSample)); } } } @@ -794,13 +818,13 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (get_bits1(gbc)) { /* Allow asymmetric application of DRC when drc_scale > 1. Amplification of quiet sounds is enhanced */ - float range = dynamic_range_tab[get_bits(gbc, 8)]; + INTFLOAT range = AC3_RANGE(get_bits(gbc, 8)); if (range > 1.0 || s->drc_scale <= 1.0) - s->dynamic_range[i] = powf(range, s->drc_scale); + s->dynamic_range[i] = AC3_DYNAMIC_RANGE(range); else s->dynamic_range[i] = range; } else if (blk == 0) { - s->dynamic_range[i] = 1.0f; + s->dynamic_range[i] = AC3_DYNAMIC_RANGE1; } } while (i--); @@ -826,6 +850,9 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (start_subband > 7) start_subband += start_subband - 7; end_subband = get_bits(gbc, 3) + 5; +#if CONFIG_AC3_FIXED + s->spx_dst_end_freq = end_freq_inv_tab[end_subband]; +#endif if (end_subband > 7) end_subband += end_subband - 7; dst_start_freq = dst_start_freq * 12 + 25; @@ -846,7 +873,9 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->spx_dst_start_freq = dst_start_freq; s->spx_src_start_freq = src_start_freq; +#if !CONFIG_AC3_FIXED s->spx_dst_end_freq = dst_end_freq; +#endif decode_band_structure(gbc, blk, s->eac3, 0, start_subband, end_subband, @@ -866,18 +895,40 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) for (ch = 1; ch <= fbw_channels; ch++) { if (s->channel_uses_spx[ch]) { if (s->first_spx_coords[ch] || get_bits1(gbc)) { - float spx_blend; + INTFLOAT spx_blend; int bin, master_spx_coord; s->first_spx_coords[ch] = 0; - spx_blend = get_bits(gbc, 5) * (1.0f/32); + spx_blend = AC3_SPX_BLEND(get_bits(gbc, 5)); master_spx_coord = get_bits(gbc, 2) * 3; bin = s->spx_src_start_freq; for (bnd = 0; bnd < s->num_spx_bands; bnd++) { int bandsize; int spx_coord_exp, spx_coord_mant; - float nratio, sblend, nblend, spx_coord; + INTFLOAT nratio, sblend, nblend; +#if CONFIG_AC3_FIXED + int64_t accu; + /* calculate blending factors */ + bandsize = s->spx_band_sizes[bnd]; + accu = (int64_t)((bin << 23) + (bandsize << 22)) * s->spx_dst_end_freq; + nratio = (int)(accu >> 32); + nratio -= spx_blend << 18; + + if (nratio < 0) { + nblend = 0; + sblend = 0x800000; + } else if (nratio > 0x7fffff) { + nblend = 0x800000; + sblend = 0; + } else { + nblend = fixed_sqrt(nratio, 23); + accu = (int64_t)nblend * 1859775393; + nblend = (int)((accu + (1<<29)) >> 30); + sblend = fixed_sqrt(0x800000 - nratio, 23); + } +#else + float spx_coord; /* calculate blending factors */ bandsize = s->spx_band_sizes[bnd]; @@ -886,6 +937,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) nblend = sqrtf(3.0f * nratio); // noise is scaled by sqrt(3) // to give unity variance sblend = sqrtf(1.0f - nratio); +#endif bin += bandsize; /* decode spx coordinates */ @@ -894,11 +946,18 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (spx_coord_exp == 15) spx_coord_mant <<= 1; else spx_coord_mant += 4; spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); - spx_coord = spx_coord_mant * (1.0f / (1 << 23)); /* multiply noise and signal blending factors by spx coordinate */ +#if CONFIG_AC3_FIXED + accu = (int64_t)nblend * spx_coord_mant; + s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); + accu = (int64_t)sblend * spx_coord_mant; + s->spx_signal_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); +#else + spx_coord = spx_coord_mant * (1.0f / (1 << 23)); s->spx_noise_blend [ch][bnd] = nblend * spx_coord; s->spx_signal_blend[ch][bnd] = sblend * spx_coord; +#endif } } } else { @@ -1255,14 +1314,19 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) /* apply scaling to coefficients (headroom, dynrng) */ for (ch = 1; ch <= s->channels; ch++) { - float gain = 1.0 / 4194304.0f; - if (s->channel_mode == AC3_CHMODE_DUALMONO) { - gain *= s->dynamic_range[2 - ch]; + INTFLOAT gain; + if(s->channel_mode == AC3_CHMODE_DUALMONO) { + gain = s->dynamic_range[2-ch]; } else { - gain *= s->dynamic_range[0]; + gain = s->dynamic_range[0]; } +#if CONFIG_AC3_FIXED + scale_coefs(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256); +#else + gain *= 1.0 / 4194304.0f; s->fmt_conv.int32_to_float_fmul_scalar(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256); +#endif } /* apply spectral extension to high frequency bins */ @@ -1287,19 +1351,24 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) do_imdct(s, s->channels); if (downmix_output) { +#if CONFIG_AC3_FIXED + ac3_downmix_c_fixed16(s->outptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 256); +#else s->ac3dsp.downmix(s->outptr, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); +#endif } } else { if (downmix_output) { - s->ac3dsp.downmix(s->xcfptr + 1, s->downmix_coeffs, - s->out_channels, s->fbw_channels, 256); + s->ac3dsp.AC3_RENAME(downmix)(s->xcfptr + 1, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 256); } if (downmix_output && !s->downmixed) { s->downmixed = 1; - s->ac3dsp.downmix(s->dlyptr, s->downmix_coeffs, s->out_channels, - s->fbw_channels, 128); + s->ac3dsp.AC3_RENAME(downmix)(s->dlyptr, s->downmix_coeffs, + s->out_channels, s->fbw_channels, 128); } do_imdct(s, s->out_channels); @@ -1320,7 +1389,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, AC3DecodeContext *s = avctx->priv_data; int blk, ch, err, ret; const uint8_t *channel_map; - const float *output[AC3_MAX_CHANNELS]; + const SHORTFLOAT *output[AC3_MAX_CHANNELS]; enum AVMatrixEncoding matrix_encoding; AVDownmixInfo *downmix_info; @@ -1447,7 +1516,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } for (ch = 0; ch < s->channels; ch++) { if (ch < s->out_channels) - s->outptr[channel_map[ch]] = (float *)frame->data[ch]; + s->outptr[channel_map[ch]] = (SHORTFLOAT *)frame->data[ch]; } for (blk = 0; blk < s->num_blocks; blk++) { if (!err && decode_audio_block(s, blk)) { @@ -1456,7 +1525,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, } if (err) for (ch = 0; ch < s->out_channels; ch++) - memcpy(((float*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], sizeof(**output) * AC3_BLOCK_SIZE); + memcpy(((SHORTFLOAT*)frame->data[ch]) + AC3_BLOCK_SIZE*blk, output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); for (ch = 0; ch < s->out_channels; ch++) output[ch] = s->outptr[channel_map[ch]]; for (ch = 0; ch < s->out_channels; ch++) { @@ -1469,7 +1538,7 @@ static int ac3_decode_frame(AVCodecContext * avctx, void *data, /* keep last block for error concealment in next frame */ for (ch = 0; ch < s->out_channels; ch++) - memcpy(s->output[ch], output[ch], sizeof(**output) * AC3_BLOCK_SIZE); + memcpy(s->output[ch], output[ch], AC3_BLOCK_SIZE*sizeof(SHORTFLOAT)); /* * AVMatrixEncoding @@ -1540,66 +1609,12 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) AC3DecodeContext *s = avctx->priv_data; ff_mdct_end(&s->imdct_512); ff_mdct_end(&s->imdct_256); +#if (CONFIG_AC3_FIXED) + av_free(s->fdsp); +#endif return 0; } #define OFFSET(x) offsetof(AC3DecodeContext, x) #define PAR (AV_OPT_FLAG_DECODING_PARAM | AV_OPT_FLAG_AUDIO_PARAM) -static const AVOption options[] = { - { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, - -{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"}, -{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, -{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, -{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, -{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, - - { NULL}, -}; - -static const AVClass ac3_decoder_class = { - .class_name = "AC3 decoder", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVCodec ff_ac3_decoder = { - .name = "ac3", - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_AC3, - .priv_data_size = sizeof (AC3DecodeContext), - .init = ac3_decode_init, - .close = ac3_decode_end, - .decode = ac3_decode_frame, - .capabilities = CODEC_CAP_DR1, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_NONE }, - .priv_class = &ac3_decoder_class, -}; - -#if CONFIG_EAC3_DECODER -static const AVClass eac3_decoder_class = { - .class_name = "E-AC3 decoder", - .item_name = av_default_item_name, - .option = options, - .version = LIBAVUTIL_VERSION_INT, -}; - -AVCodec ff_eac3_decoder = { - .name = "eac3", - .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), - .type = AVMEDIA_TYPE_AUDIO, - .id = AV_CODEC_ID_EAC3, - .priv_data_size = sizeof (AC3DecodeContext), - .init = ac3_decode_init, - .close = ac3_decode_end, - .decode = ac3_decode_frame, - .capabilities = CODEC_CAP_DR1, - .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, - AV_SAMPLE_FMT_NONE }, - .priv_class = &eac3_decoder_class, -}; -#endif diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 58d8ee6..255b9df 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -51,6 +51,7 @@ #define AVCODEC_AC3DEC_H #include "libavutil/float_dsp.h" +#include "libavutil/fixed_dsp.h" #include "libavutil/lfg.h" #include "ac3.h" #include "ac3dsp.h" @@ -138,8 +139,8 @@ typedef struct AC3DecodeContext { int num_spx_bands; ///< number of spx bands (nspxbnds) uint8_t spx_band_sizes[SPX_MAX_BANDS]; ///< number of bins in each spx band uint8_t first_spx_coords[AC3_MAX_CHANNELS]; ///< first spx coordinates states (firstspxcos) - float spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact) - float spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact) + INTFLOAT spx_noise_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS]; ///< spx noise blending factor (nblendfact) + INTFLOAT spx_signal_blend[AC3_MAX_CHANNELS][SPX_MAX_BANDS];///< spx signal blending factor (sblendfact) ///@} ///@name Adaptive hybrid transform @@ -151,15 +152,15 @@ typedef struct AC3DecodeContext { int fbw_channels; ///< number of full-bandwidth channels int channels; ///< number of total channels int lfe_ch; ///< index of LFE channel - float downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients + SHORTFLOAT downmix_coeffs[AC3_MAX_CHANNELS][2]; ///< stereo downmix coefficients int downmixed; ///< indicates if coeffs are currently downmixed int output_mode; ///< output channel configuration int out_channels; ///< number of output channels ///@} ///@name Dynamic range - float dynamic_range[2]; ///< dynamic range - float drc_scale; ///< percentage of dynamic range compression to be applied + INTFLOAT dynamic_range[2]; ///< dynamic range + INTFLOAT drc_scale; ///< percentage of dynamic range compression to be applied ///@} ///@name Bandwidth @@ -207,22 +208,26 @@ typedef struct AC3DecodeContext { ///@name Optimization DSPContext dsp; ///< for optimization +#if CONFIG_AC3_FIXED + AVFixedDSPContext *fdsp; +#else AVFloatDSPContext fdsp; +#endif AC3DSPContext ac3dsp; FmtConvertContext fmt_conv; ///< optimized conversion functions ///@} - float *outptr[AC3_MAX_CHANNELS]; - float *xcfptr[AC3_MAX_CHANNELS]; - float *dlyptr[AC3_MAX_CHANNELS]; + SHORTFLOAT *outptr[AC3_MAX_CHANNELS]; + INTFLOAT *xcfptr[AC3_MAX_CHANNELS]; + INTFLOAT *dlyptr[AC3_MAX_CHANNELS]; ///@name Aligned arrays - DECLARE_ALIGNED(16, int32_t, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients - DECLARE_ALIGNED(32, float, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients - DECLARE_ALIGNED(32, float, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block - DECLARE_ALIGNED(32, float, window)[AC3_BLOCK_SIZE]; ///< window coefficients - DECLARE_ALIGNED(32, float, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing - DECLARE_ALIGNED(32, float, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing + DECLARE_ALIGNED(16, int, fixed_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< fixed-point transform coefficients + DECLARE_ALIGNED(32, INTFLOAT, transform_coeffs)[AC3_MAX_CHANNELS][AC3_MAX_COEFS]; ///< transform coefficients + DECLARE_ALIGNED(32, INTFLOAT, delay)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< delay - added to the next block + DECLARE_ALIGNED(32, INTFLOAT, window)[AC3_BLOCK_SIZE]; ///< window coefficients + DECLARE_ALIGNED(32, INTFLOAT, tmp_output)[AC3_BLOCK_SIZE]; ///< temporary storage for output before windowing + DECLARE_ALIGNED(32, SHORTFLOAT, output)[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE]; ///< output after imdct transform and windowing DECLARE_ALIGNED(32, uint8_t, input_buffer)[AC3_FRAME_BUFFER_SIZE + FF_INPUT_BUFFER_PADDING_SIZE]; ///< temp buffer to prevent overread ///@} } AC3DecodeContext; diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c new file mode 100644 index 0000000..1eb9a0b --- /dev/null +++ b/libavcodec/ac3dec_fixed.c @@ -0,0 +1,176 @@ +/* + * Copyright (c) 2012 + * MIPS Technologies, Inc., California. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * 3. Neither the name of the MIPS Technologies, Inc., nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE MIPS TECHNOLOGIES, INC. ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE MIPS TECHNOLOGIES, INC. BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * Author: Stanislav Ocovaj (socovaj@mips.com) + * + * AC3 fixed-point decoder for MIPS platforms + * + * 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 + */ + +#define FFT_FLOAT 0 +#define CONFIG_AC3_FIXED 1 +#define FFT_FIXED_32 1 +#include "ac3dec.h" + + +/** + * Table for center mix levels + * reference: Section 5.4.2.4 cmixlev + */ +static const uint8_t center_levels[4] = { 4, 5, 6, 5 }; + +/** + * Table for surround mix levels + * reference: Section 5.4.2.5 surmixlev + */ +static const uint8_t surround_levels[4] = { 4, 6, 7, 6 }; + +int end_freq_inv_tab[8] = +{ + 50529027, 44278013, 39403370, 32292987, 27356480, 23729101, 20951060, 18755316 +}; + +static void scale_coefs ( + int32_t *dst, + const int32_t *src, + int dynrng, + int len) +{ + int i, shift, round; + int16_t mul; + int temp, temp1, temp2, temp3, temp4, temp5, temp6, temp7; + + mul = (dynrng & 0x1f) + 0x20; + shift = 4 - ((dynrng << 24) >> 29); + round = 1 << (shift-1); + for (i=0; i<len; i+=8) { + + temp = src[i] * mul; + temp1 = src[i+1] * mul; + temp = temp + round; + temp2 = src[i+2] * mul; + + temp1 = temp1 + round; + dst[i] = temp >> shift; + temp3 = src[i+3] * mul; + temp2 = temp2 + round; + + dst[i+1] = temp1 >> shift; + temp4 = src[i + 4] * mul; + temp3 = temp3 + round; + dst[i+2] = temp2 >> shift; + + temp5 = src[i+5] * mul; + temp4 = temp4 + round; + dst[i+3] = temp3 >> shift; + temp6 = src[i+6] * mul; + + dst[i+4] = temp4 >> shift; + temp5 = temp5 + round; + temp7 = src[i+7] * mul; + temp6 = temp6 + round; + + dst[i+5] = temp5 >> shift; + temp7 = temp7 + round; + dst[i+6] = temp6 >> shift; + dst[i+7] = temp7 >> shift; + + } +} + +/** + * Downmix samples from original signal to stereo or mono (this is for 16-bit samples + * and fixed point decoder - original (for 32-bit samples) is in ac3dsp.c). + */ +static void ac3_downmix_c_fixed16(int16_t **samples, int16_t (*matrix)[2], + int out_ch, int in_ch, int len) +{ + int i, j; + int v0, v1; + if (out_ch == 2) { + for (i = 0; i < len; i++) { + v0 = v1 = 0; + for (j = 0; j < in_ch; j++) { + v0 += samples[j][i] * matrix[j][0]; + v1 += samples[j][i] * matrix[j][1]; + } + samples[0][i] = (v0+2048)>>12; + samples[1][i] = (v1+2048)>>12; + } + } else if (out_ch == 1) { + for (i = 0; i < len; i++) { + v0 = 0; + for (j = 0; j < in_ch; j++) + v0 += samples[j][i] * matrix[j][0]; + samples[0][i] = (v0+2048)>>12; + } + } +} + +#include "ac3dec.c" + +static const AVOption options[] = { + { NULL}, +}; + +static const AVClass ac3_decoder_class = { + .class_name = "Fixed-Point AC-3 Decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_ac3_fixed_decoder = { + .name = "ac3_fixed", + .type = AVMEDIA_TYPE_AUDIO, + .id = CODEC_ID_AC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_S16P, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3_decoder_class, +}; diff --git a/libavcodec/ac3dec_float.c b/libavcodec/ac3dec_float.c new file mode 100644 index 0000000..7108921 --- /dev/null +++ b/libavcodec/ac3dec_float.c @@ -0,0 +1,89 @@ +/* + * AC-3 Audio Decoder + * This code was developed as part of Google Summer of Code 2006. + * E-AC-3 support was added as part of Google Summer of Code 2007. + * + * Copyright (c) 2006 Kartikey Mahendra BHATT (bhattkm at gmail dot com) + * Copyright (c) 2007-2008 Bartlomiej Wolowiec <bartek.wolowiec@gmail.com> + * Copyright (c) 2007 Justin Ruggles <justin.ruggles@gmail.com> + * + * 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 + */ + +/** + * Upmix delay samples from stereo to original channel layout. + */ +#include "ac3dec.h" +#include "ac3dec.c" + +static const AVOption options[] = { + { "drc_scale", "percentage of dynamic range compression to apply", OFFSET(drc_scale), AV_OPT_TYPE_FLOAT, {.dbl = 1.0}, 0.0, 6.0, PAR }, + +{"dmix_mode", "Preferred Stereo Downmix Mode", OFFSET(preferred_stereo_downmix), AV_OPT_TYPE_INT, {.i64 = -1 }, -1, 2, 0, "dmix_mode"}, +{"ltrt_cmixlev", "Lt/Rt Center Mix Level", OFFSET(ltrt_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"ltrt_surmixlev", "Lt/Rt Surround Mix Level", OFFSET(ltrt_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_cmixlev", "Lo/Ro Center Mix Level", OFFSET(loro_center_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, +{"loro_surmixlev", "Lo/Ro Surround Mix Level", OFFSET(loro_surround_mix_level), AV_OPT_TYPE_FLOAT, {.dbl = -1.0 }, -1.0, 2.0, 0}, + + { NULL}, +}; + +static const AVClass ac3_decoder_class = { + .class_name = "AC3 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_ac3_decoder = { + .name = "ac3", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_AC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &ac3_decoder_class, +}; + +#if CONFIG_EAC3_DECODER +static const AVClass eac3_decoder_class = { + .class_name = "E-AC3 decoder", + .item_name = av_default_item_name, + .option = options, + .version = LIBAVUTIL_VERSION_INT, +}; + +AVCodec ff_eac3_decoder = { + .name = "eac3", + .type = AVMEDIA_TYPE_AUDIO, + .id = AV_CODEC_ID_EAC3, + .priv_data_size = sizeof (AC3DecodeContext), + .init = ac3_decode_init, + .close = ac3_decode_end, + .decode = ac3_decode_frame, + .capabilities = CODEC_CAP_DR1, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52B (AC-3, E-AC-3)"), + .sample_fmts = (const enum AVSampleFormat[]) { AV_SAMPLE_FMT_FLTP, + AV_SAMPLE_FMT_NONE }, + .priv_class = &eac3_decoder_class, +}; +#endif diff --git a/libavcodec/ac3dsp.c b/libavcodec/ac3dsp.c index 0d5ea39..b746817 100644 --- a/libavcodec/ac3dsp.c +++ b/libavcodec/ac3dsp.c @@ -239,6 +239,31 @@ static void ac3_downmix_c(float **samples, float (*matrix)[2], } } +static void ac3_downmix_c_fixed(int32_t **samples, int16_t (*matrix)[2], + int out_ch, int in_ch, int len) +{ + int i, j; + int64_t v0, v1; + if (out_ch == 2) { + for (i = 0; i < len; i++) { + v0 = v1 = 0; + for (j = 0; j < in_ch; j++) { + v0 += (int64_t)samples[j][i] * matrix[j][0]; + v1 += (int64_t)samples[j][i] * matrix[j][1]; + } + samples[0][i] = (v0+2048)>>12; + samples[1][i] = (v1+2048)>>12; + } + } else if (out_ch == 1) { + for (i = 0; i < len; i++) { + v0 = 0; + for (j = 0; j < in_ch; j++) + v0 += (int64_t)samples[j][i] * matrix[j][0]; + samples[0][i] = (v0+2048)>>12; + } + } +} + static void apply_window_int16_c(int16_t *output, const int16_t *input, const int16_t *window, unsigned int len) { @@ -266,6 +291,7 @@ av_cold void ff_ac3dsp_init(AC3DSPContext *c, int bit_exact) c->sum_square_butterfly_int32 = ac3_sum_square_butterfly_int32_c; c->sum_square_butterfly_float = ac3_sum_square_butterfly_float_c; c->downmix = ac3_downmix_c; + c->downmix_fixed = ac3_downmix_c_fixed; c->apply_window_int16 = apply_window_int16_c; if (ARCH_ARM) diff --git a/libavcodec/ac3dsp.h b/libavcodec/ac3dsp.h index f18583c..ed98c8c 100644 --- a/libavcodec/ac3dsp.h +++ b/libavcodec/ac3dsp.h @@ -135,6 +135,9 @@ typedef struct AC3DSPContext { void (*downmix)(float **samples, float (*matrix)[2], int out_ch, int in_ch, int len); + void (*downmix_fixed)(int32_t **samples, int16_t (*matrix)[2], int out_ch, + int in_ch, int len); + /** * Apply symmetric window in 16-bit fixed-point. * @param output destination array diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 10edd39..c55a809 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -323,7 +323,7 @@ void avcodec_register_all(void) REGISTER_ENCDEC (AAC, aac); REGISTER_DECODER(AAC_LATM, aac_latm); REGISTER_ENCDEC (AC3, ac3); - REGISTER_ENCODER(AC3_FIXED, ac3_fixed); + REGISTER_ENCDEC (AC3_FIXED, ac3_fixed); REGISTER_ENCDEC (ALAC, alac); REGISTER_DECODER(ALS, als); REGISTER_DECODER(AMRNB, amrnb); diff --git a/libavcodec/kbdwin.c b/libavcodec/kbdwin.c index 5a62e9d..bf32aeb 100644 --- a/libavcodec/kbdwin.c +++ b/libavcodec/kbdwin.c @@ -45,3 +45,13 @@ av_cold void ff_kbd_window_init(float *window, float alpha, int n) for (i = 0; i < n; i++) window[i] = sqrt(local_window[i] / sum); } + +av_cold void ff_kbd_window_init_fixed(int32_t *window, float alpha, int n) +{ + int i; + float local_window[FF_KBD_WINDOW_MAX]; + + ff_kbd_window_init(local_window, alpha, n); + for (i = 0; i < n; i++) + window[i] = (int)floor(2147483647.0 * local_window[i] + 0.5); +} diff --git a/libavcodec/kbdwin.h b/libavcodec/kbdwin.h index 4b93975..2e02e10 100644 --- a/libavcodec/kbdwin.h +++ b/libavcodec/kbdwin.h @@ -31,5 +31,6 @@ * @param n size of half window, max FF_KBD_WINDOW_MAX */ void ff_kbd_window_init(float *window, float alpha, int n); +void ff_kbd_window_init_fixed(int32_t *window, float alpha, int n); #endif /* AVCODEC_KBDWIN_H */ diff --git a/libavcodec/version.h b/libavcodec/version.h index 21f5dea..19b4934 100644 --- a/libavcodec/version.h +++ b/libavcodec/version.h @@ -29,7 +29,7 @@ #include "libavutil/version.h" #define LIBAVCODEC_VERSION_MAJOR 55 -#define LIBAVCODEC_VERSION_MINOR 55 +#define LIBAVCODEC_VERSION_MINOR 56 #define LIBAVCODEC_VERSION_MICRO 107 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ -- 1.8.2.1
On Tue, Apr 01, 2014 at 04:31:08PM +0200, Nedeljko Babic wrote:
From: Nedeljko Babic <nbabic@mips.com>
Signed-off-by: Nedeljko Babic <nbabic@mips.com>
applied thanks [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB No great genius has ever existed without some touch of madness. -- Aristotle
From: Michael Niedermayer <michaelni@gmx.at> the CONFIG_ prefix is used by configure, using it for other things is potentially confusing to the reader Signeoff-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavcodec/ac3.h | 10 +++++----- libavcodec/ac3dec.c | 22 +++++++++++----------- libavcodec/ac3dec.h | 2 +- libavcodec/ac3dec_fixed.c | 2 +- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/libavcodec/ac3.h b/libavcodec/ac3.h index ac3936d..542f79d 100644 --- a/libavcodec/ac3.h +++ b/libavcodec/ac3.h @@ -51,11 +51,11 @@ #define EXP_D25 2 #define EXP_D45 3 -#ifndef CONFIG_AC3_FIXED -#define CONFIG_AC3_FIXED 0 +#ifndef USE_FIXED +#define USE_FIXED 0 #endif -#if CONFIG_AC3_FIXED +#if USE_FIXED #define FFT_FLOAT 0 @@ -75,7 +75,7 @@ #define INTFLOAT int #define SHORTFLOAT int16_t -#else /* CONFIG_AC3_FIXED */ +#else /* USE_FIXED */ #define FIXR(x) ((float)(x)) #define FIXR12(x) ((float)(x)) @@ -93,7 +93,7 @@ #define INTFLOAT float #define SHORTFLOAT float -#endif /* CONFIG_AC3_FIXED */ +#endif /* USE_FIXED */ #define AC3_LEVEL(x) ROUND15((x) * FIXR15(0.7071067811865476)) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index 1d97df9..f011a3b 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -182,7 +182,7 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) AC3_RENAME(ff_kbd_window_init)(s->window, 5.0, 256); ff_dsputil_init(&s->dsp, avctx); -#if (CONFIG_AC3_FIXED) +#if (USE_FIXED) s->fdsp = avpriv_alloc_fixed_dsp(avctx->flags & CODEC_FLAG_BITEXACT); #else avpriv_float_dsp_init(&s->fdsp, avctx->flags & CODEC_FLAG_BITEXACT); @@ -192,7 +192,7 @@ static av_cold int ac3_decode_init(AVCodecContext *avctx) ff_fmt_convert_init(&s->fmt_conv, avctx); av_lfg_init(&s->dith_state, 0); - if (CONFIG_AC3_FIXED) + if (USE_FIXED) avctx->sample_fmt = AV_SAMPLE_FMT_S16P; else avctx->sample_fmt = AV_SAMPLE_FMT_FLTP; @@ -664,7 +664,7 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) for (i = 0; i < 128; i++) x[i] = s->transform_coeffs[ch][2 * i]; s->imdct_256.imdct_half(&s->imdct_256, s->tmp_output, x); -#if CONFIG_AC3_FIXED +#if USE_FIXED s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], s->tmp_output, s->window, 128, 8); #else @@ -676,7 +676,7 @@ static inline void do_imdct(AC3DecodeContext *s, int channels) s->imdct_256.imdct_half(&s->imdct_256, s->delay[ch - 1], x); } else { s->imdct_512.imdct_half(&s->imdct_512, s->tmp_output, s->transform_coeffs[ch]); -#if CONFIG_AC3_FIXED +#if USE_FIXED s->fdsp->vector_fmul_window_scaled(s->outptr[ch - 1], s->delay[ch - 1], s->tmp_output, s->window, 128, 8); #else @@ -850,7 +850,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) if (start_subband > 7) start_subband += start_subband - 7; end_subband = get_bits(gbc, 3) + 5; -#if CONFIG_AC3_FIXED +#if USE_FIXED s->spx_dst_end_freq = end_freq_inv_tab[end_subband]; #endif if (end_subband > 7) @@ -873,7 +873,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->spx_dst_start_freq = dst_start_freq; s->spx_src_start_freq = src_start_freq; -#if !CONFIG_AC3_FIXED +#if !USE_FIXED s->spx_dst_end_freq = dst_end_freq; #endif @@ -907,7 +907,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) int bandsize; int spx_coord_exp, spx_coord_mant; INTFLOAT nratio, sblend, nblend; -#if CONFIG_AC3_FIXED +#if USE_FIXED int64_t accu; /* calculate blending factors */ bandsize = s->spx_band_sizes[bnd]; @@ -948,7 +948,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) spx_coord_mant <<= (25 - spx_coord_exp - master_spx_coord); /* multiply noise and signal blending factors by spx coordinate */ -#if CONFIG_AC3_FIXED +#if USE_FIXED accu = (int64_t)nblend * spx_coord_mant; s->spx_noise_blend[ch][bnd] = (int)((accu + (1<<22)) >> 23); accu = (int64_t)sblend * spx_coord_mant; @@ -1320,7 +1320,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) } else { gain = s->dynamic_range[0]; } -#if CONFIG_AC3_FIXED +#if USE_FIXED scale_coefs(s->transform_coeffs[ch], s->fixed_coeffs[ch], gain, 256); #else gain *= 1.0 / 4194304.0f; @@ -1351,7 +1351,7 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) do_imdct(s, s->channels); if (downmix_output) { -#if CONFIG_AC3_FIXED +#if USE_FIXED ac3_downmix_c_fixed16(s->outptr, s->downmix_coeffs, s->out_channels, s->fbw_channels, 256); #else @@ -1609,7 +1609,7 @@ static av_cold int ac3_decode_end(AVCodecContext *avctx) AC3DecodeContext *s = avctx->priv_data; ff_mdct_end(&s->imdct_512); ff_mdct_end(&s->imdct_256); -#if (CONFIG_AC3_FIXED) +#if (USE_FIXED) av_free(s->fdsp); #endif diff --git a/libavcodec/ac3dec.h b/libavcodec/ac3dec.h index 255b9df..5196d90 100644 --- a/libavcodec/ac3dec.h +++ b/libavcodec/ac3dec.h @@ -208,7 +208,7 @@ typedef struct AC3DecodeContext { ///@name Optimization DSPContext dsp; ///< for optimization -#if CONFIG_AC3_FIXED +#if USE_FIXED AVFixedDSPContext *fdsp; #else AVFloatDSPContext fdsp; diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index 1eb9a0b..c1e0307 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -48,7 +48,7 @@ */ #define FFT_FLOAT 0 -#define CONFIG_AC3_FIXED 1 +#define USE_FIXED 1 #define FFT_FIXED_32 1 #include "ac3dec.h" -- 1.8.2.1
On Tue, Apr 01, 2014 at 04:31:09PM +0200, Nedeljko Babic wrote:
From: Michael Niedermayer <michaelni@gmx.at>
the CONFIG_ prefix is used by configure, using it for other things is potentially confusing to the reader
Signeoff-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com>
applied [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Awnsering whenever a program halts or runs forever is On a turing machine, in general impossible (turings halting problem). On any real computer, always possible as a real computer has a finite number of states N, and will either halt in less than N cycles or never halt.
From: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavcodec/ac3dec.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/libavcodec/ac3dec.c b/libavcodec/ac3dec.c index f011a3b..e75be7e 100644 --- a/libavcodec/ac3dec.c +++ b/libavcodec/ac3dec.c @@ -873,9 +873,8 @@ static int decode_audio_block(AC3DecodeContext *s, int blk) s->spx_dst_start_freq = dst_start_freq; s->spx_src_start_freq = src_start_freq; -#if !USE_FIXED - s->spx_dst_end_freq = dst_end_freq; -#endif + if (!USE_FIXED) + s->spx_dst_end_freq = dst_end_freq; decode_band_structure(gbc, blk, s->eac3, 0, start_subband, end_subband, -- 1.8.2.1
On Tue, Apr 01, 2014 at 04:31:10PM +0200, Nedeljko Babic wrote:
From: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com>
applied [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB In a rich man's house there is no place to spit but his face. -- Diogenes of Sinope
From: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavcodec/ac3dec_fixed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libavcodec/ac3dec_fixed.c b/libavcodec/ac3dec_fixed.c index c1e0307..c6cbeb9 100644 --- a/libavcodec/ac3dec_fixed.c +++ b/libavcodec/ac3dec_fixed.c @@ -163,7 +163,7 @@ static const AVClass ac3_decoder_class = { AVCodec ff_ac3_fixed_decoder = { .name = "ac3_fixed", .type = AVMEDIA_TYPE_AUDIO, - .id = CODEC_ID_AC3, + .id = AV_CODEC_ID_AC3, .priv_data_size = sizeof (AC3DecodeContext), .init = ac3_decode_init, .close = ac3_decode_end, -- 1.8.2.1
On Tue, Apr 01, 2014 at 04:31:11PM +0200, Nedeljko Babic wrote:
From: Michael Niedermayer <michaelni@gmx.at>
Signed-off-by: Michael Niedermayer <michaelni@gmx.at> Signed-off-by: Nedeljko Babic <nbabic@mips.com> --- libavcodec/ac3dec_fixed.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
applied [...] -- Michael GnuPG fingerprint: 9FF2128B147EF6730BADF133611EC787040B0FAB Awnsering whenever a program halts or runs forever is On a turing machine, in general impossible (turings halting problem). On any real computer, always possible as a real computer has a finite number of states N, and will either halt in less than N cycles or never halt.
participants (3)
-
James Almer -
Michael Niedermayer -
Nedeljko Babic