From 6fd96d1a85f3b81a1dbf08b79ba395506471ded0 Mon Sep 17 00:00:00 2001 From: Justin Ruggles Date: Tue, 4 Jan 2011 11:53:44 +0000 Subject: [PATCH] Change the AC-3 encoder to use floating-point. Fixed-point AC-3 encoder renamed to ac3_fixed. Regression test acodec-ac3 renamed to acodec-ac3_fixed. Regression test lavf-rm changed to use ac3_fixed encoder. Originally committed as revision 26209 to svn://svn.ffmpeg.org/ffmpeg/trunk --- Changelog | 1 + configure | 3 +- libavcodec/Makefile | 3 +- libavcodec/ac3enc.c | 11 ++- libavcodec/ac3enc_fixed.c | 5 +- libavcodec/ac3enc_float.c | 117 ++++++++++++++++++++++++++++ libavcodec/ac3enc_float.h | 46 +++++++++++ libavcodec/allcodecs.c | 1 + libavcodec/avcodec.h | 2 +- tests/codec-regression.sh | 4 +- tests/lavf-regression.sh | 2 +- tests/ref/acodec/{ac3 => ac3_fixed} | 0 12 files changed, 186 insertions(+), 9 deletions(-) create mode 100644 libavcodec/ac3enc_float.c create mode 100644 libavcodec/ac3enc_float.h rename tests/ref/acodec/{ac3 => ac3_fixed} (100%) diff --git a/Changelog b/Changelog index 41ece6c503..6a25ade822 100644 --- a/Changelog +++ b/Changelog @@ -70,6 +70,7 @@ version : - Windows Televison (WTV) demuxer - FFmpeg metadata format muxer and demuxer - SubRip (srt) subtitle decoder +- floating-point AC-3 encoder added version 0.6: diff --git a/configure b/configure index d756477c76..949f907a61 100755 --- a/configure +++ b/configure @@ -1193,6 +1193,7 @@ aac_decoder_select="mdct rdft" aac_encoder_select="mdct" aac_latm_decoder_select="aac_decoder aac_latm_parser" ac3_decoder_select="mdct ac3_parser" +ac3_encoder_select="mdct" alac_encoder_select="lpc" amrnb_decoder_select="lsp" amrwb_decoder_select="lsp" @@ -1453,7 +1454,6 @@ set_ne_test_deps(){ } test_deps _encoder _decoder \ - ac3 \ adpcm_g726=g726 \ adpcm_ima_qt \ adpcm_ima_wav \ @@ -1525,6 +1525,7 @@ test_deps _muxer _demuxer \ wav \ yuv4mpegpipe=yuv4mpeg \ +ac3_fixed_test_deps="ac3_fixed_encoder ac3_decoder rm_muxer rm_demuxer" mpg_test_deps="mpeg1system_muxer mpegps_demuxer" set_ne_test_deps pixdesc diff --git a/libavcodec/Makefile b/libavcodec/Makefile index 3d13e4a0d3..ee16b91510 100644 --- a/libavcodec/Makefile +++ b/libavcodec/Makefile @@ -54,7 +54,8 @@ OBJS-$(CONFIG_AAC_ENCODER) += aacenc.o aaccoder.o \ mpeg4audio.o OBJS-$(CONFIG_AASC_DECODER) += aasc.o msrledec.o OBJS-$(CONFIG_AC3_DECODER) += ac3dec.o ac3dec_data.o ac3.o -OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_fixed.o ac3tab.o ac3.o +OBJS-$(CONFIG_AC3_ENCODER) += ac3enc_float.o ac3tab.o ac3.o +OBJS-$(CONFIG_AC3_FIXED_ENCODER) += ac3enc_fixed.o ac3tab.o ac3.o OBJS-$(CONFIG_ALAC_DECODER) += alac.o OBJS-$(CONFIG_ALAC_ENCODER) += alacenc.o OBJS-$(CONFIG_ALS_DECODER) += alsdec.o bgmc.o mpeg4audio.o diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c index ec678ee6f4..902aabf795 100644 --- a/libavcodec/ac3enc.c +++ b/libavcodec/ac3enc.c @@ -37,6 +37,11 @@ #include "audioconvert.h" +#ifndef CONFIG_AC3ENC_FLOAT +#define CONFIG_AC3ENC_FLOAT 0 +#endif + + /** Maximum number of exponent groups. +1 for separate DC exponent. */ #define AC3_MAX_EXP_GROUPS 85 @@ -44,7 +49,11 @@ #define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits))) +#if CONFIG_AC3ENC_FLOAT +#include "ac3enc_float.h" +#else #include "ac3enc_fixed.h" +#endif /** @@ -130,7 +139,7 @@ typedef struct AC3EncodeContext { } AC3EncodeContext; -/* prototypes for functions in ac3enc_fixed.c */ +/* prototypes for functions in ac3enc_fixed.c and ac3_float.c */ static av_cold void mdct_end(AC3MDCTContext *mdct); diff --git a/libavcodec/ac3enc_fixed.c b/libavcodec/ac3enc_fixed.c index 6505b7a0ea..9d3b195ded 100644 --- a/libavcodec/ac3enc_fixed.c +++ b/libavcodec/ac3enc_fixed.c @@ -26,6 +26,7 @@ * fixed-point AC-3 encoder. */ +#undef CONFIG_AC3ENC_FLOAT #include "ac3enc.c" @@ -413,8 +414,8 @@ int main(void) #endif /* TEST */ -AVCodec ac3_encoder = { - "ac3", +AVCodec ac3_fixed_encoder = { + "ac3_fixed", AVMEDIA_TYPE_AUDIO, CODEC_ID_AC3, sizeof(AC3EncodeContext), diff --git a/libavcodec/ac3enc_float.c b/libavcodec/ac3enc_float.c new file mode 100644 index 0000000000..82d806bc06 --- /dev/null +++ b/libavcodec/ac3enc_float.c @@ -0,0 +1,117 @@ +/* + * The simplest AC-3 encoder + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * 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 + * floating-point AC-3 encoder. + */ + +#define CONFIG_AC3ENC_FLOAT 1 +#include "ac3enc.c" + + +/** + * Finalize MDCT and free allocated memory. + */ +static av_cold void mdct_end(AC3MDCTContext *mdct) +{ + ff_mdct_end(&mdct->fft); + av_freep(&mdct->window); +} + + +/** + * Initialize MDCT tables. + * @param nbits log2(MDCT size) + */ +static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct, + int nbits) +{ + float *window; + int n, n2; + + n = 1 << nbits; + n2 = n >> 1; + + window = av_malloc(n2 * sizeof(*window)); + if (!window) { + av_log(avctx, AV_LOG_ERROR, "Cannot allocate memory.\n"); + 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); +} + + +/** + * Calculate a 512-point MDCT + * @param out 256 output frequency coefficients + * @param in 512 windowed input audio samples + */ +static void mdct512(AC3MDCTContext *mdct, float *out, float *in) +{ + ff_mdct_calc(&mdct->fft, out, in); +} + + +/** + * Apply KBD window to input samples prior to MDCT. + */ +static void apply_window(float *output, const float *input, + const float *window, int n) +{ + int i; + int n2 = n >> 1; + + for (i = 0; i < n2; i++) { + output[i] = input[i] * window[i]; + output[n-i-1] = input[n-i-1] * window[i]; + } +} + + +/** + * Normalize the input samples to use the maximum available precision. + */ +static int normalize_samples(AC3EncodeContext *s) +{ + /* Normalization is not needed for floating-point samples, so just return 0 */ + return 0; +} + + +AVCodec ac3_encoder = { + "ac3", + AVMEDIA_TYPE_AUDIO, + CODEC_ID_AC3, + sizeof(AC3EncodeContext), + ac3_encode_init, + ac3_encode_frame, + ac3_encode_close, + NULL, + .sample_fmts = (const enum AVSampleFormat[]){AV_SAMPLE_FMT_FLT,AV_SAMPLE_FMT_NONE}, + .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), + .channel_layouts = ac3_channel_layouts, +}; diff --git a/libavcodec/ac3enc_float.h b/libavcodec/ac3enc_float.h new file mode 100644 index 0000000000..1cd3681ae9 --- /dev/null +++ b/libavcodec/ac3enc_float.h @@ -0,0 +1,46 @@ +/* + * The simplest AC-3 encoder + * Copyright (c) 2000 Fabrice Bellard + * Copyright (c) 2006-2010 Justin Ruggles + * Copyright (c) 2006-2010 Prakash Punnoor + * + * 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 + * floating-point AC-3 encoder header. + */ + +#ifndef AVCODEC_AC3ENC_FLOAT_H +#define AVCODEC_AC3ENC_FLOAT_H + +#include "fft.h" + + +typedef float SampleType; +typedef float CoefType; + +#define SCALE_COEF(a) SCALE_FLOAT((a), 24) + + +typedef struct AC3MDCTContext { + const float *window; ///< MDCT window function + FFTContext fft; ///< FFT context for MDCT calculation +} AC3MDCTContext; + +#endif /* AVCODEC_AC3ENC_FLOAT_H */ diff --git a/libavcodec/allcodecs.c b/libavcodec/allcodecs.c index 5bcd9120cd..5ba199861e 100644 --- a/libavcodec/allcodecs.c +++ b/libavcodec/allcodecs.c @@ -222,6 +222,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 (ALAC, alac); REGISTER_DECODER (ALS, als); REGISTER_DECODER (AMRNB, amrnb); diff --git a/libavcodec/avcodec.h b/libavcodec/avcodec.h index 8b7320f2c1..828b07ac24 100644 --- a/libavcodec/avcodec.h +++ b/libavcodec/avcodec.h @@ -32,7 +32,7 @@ #include "libavutil/cpu.h" #define LIBAVCODEC_VERSION_MAJOR 52 -#define LIBAVCODEC_VERSION_MINOR 101 +#define LIBAVCODEC_VERSION_MINOR 102 #define LIBAVCODEC_VERSION_MICRO 0 #define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \ diff --git a/tests/codec-regression.sh b/tests/codec-regression.sh index 2a2ca1cb21..71d50a1298 100755 --- a/tests/codec-regression.sh +++ b/tests/codec-regression.sh @@ -269,8 +269,8 @@ do_audio_decoding $tiny_psnr $pcm_dst $pcm_ref 2 1924 >> $logfile fi -if [ -n "$do_ac3" ] ; then -do_audio_encoding ac3.rm "" -vn +if [ -n "$do_ac3_fixed" ] ; then +do_audio_encoding ac3.rm "" "-vn -acodec ac3_fixed" # binaries configured with --disable-sse decode ac3 differently #do_audio_decoding #$tiny_psnr $pcm_dst $pcm_ref 2 1024 >> $logfile diff --git a/tests/lavf-regression.sh b/tests/lavf-regression.sh index 218a70f3af..736629bb67 100755 --- a/tests/lavf-regression.sh +++ b/tests/lavf-regression.sh @@ -57,7 +57,7 @@ fi if [ -n "$do_rm" ] ; then file=${outfile}lavf.rm -do_ffmpeg $file -t 1 -qscale 10 -f image2 -vcodec pgmyuv -i $raw_src -f s16le -i $pcm_src +do_ffmpeg $file -t 1 -qscale 10 -f image2 -vcodec pgmyuv -i $raw_src -f s16le -i $pcm_src -acodec ac3_fixed # broken #do_ffmpeg_crc $file -i $target_path/$file fi diff --git a/tests/ref/acodec/ac3 b/tests/ref/acodec/ac3_fixed similarity index 100% rename from tests/ref/acodec/ac3 rename to tests/ref/acodec/ac3_fixed