* Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
* Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
*
- * This file is part of Libav.
+ * This file is part of FFmpeg.
*
- * Libav is free software; you can redistribute it and/or
+ * 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.
*
- * Libav is distributed in the hope that it will be useful,
+ * 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 Libav; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
//#define DEBUG
//#define ASSERT_LEVEL 2
+#include <stdint.h>
+
#include "libavutil/audioconvert.h"
#include "libavutil/avassert.h"
#include "libavutil/crc.h"
#include "ac3dsp.h"
#include "ac3.h"
#include "audioconvert.h"
+#include "fft.h"
#ifndef CONFIG_AC3ENC_FLOAT
#define AC3_REMATRIXING_NONE 1
#define AC3_REMATRIXING_ALWAYS 3
-/** Scale a float value by 2^bits and convert to an integer. */
-#define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits)))
-
-
#if CONFIG_AC3ENC_FLOAT
-#include "ac3enc_float.h"
+#define MAC_COEF(d,a,b) ((d)+=(a)*(b))
+typedef float SampleType;
+typedef float CoefType;
+typedef float CoefSumType;
#else
-#include "ac3enc_fixed.h"
+#define MAC_COEF(d,a,b) MAC64(d,a,b)
+typedef int16_t SampleType;
+typedef int32_t CoefType;
+typedef int64_t CoefSumType;
#endif
-
-/**
- * Encoding Options used by AVOption.
- */
-typedef struct AC3EncOptions {
- /* AC-3 metadata options*/
- int dialogue_level;
- int bitstream_mode;
- float center_mix_level;
- float surround_mix_level;
- int dolby_surround_mode;
- int audio_production_info;
- int mixing_level;
- int room_type;
- int copyright;
- int original;
- int extended_bsi_1;
- int preferred_stereo_downmix;
- float ltrt_center_mix_level;
- float ltrt_surround_mix_level;
- float loro_center_mix_level;
- float loro_surround_mix_level;
- int extended_bsi_2;
- int dolby_surround_ex_mode;
- int dolby_headphone_mode;
- int ad_converter_type;
-
- /* other encoding options */
- int allow_per_frame_metadata;
-} AC3EncOptions;
+typedef struct AC3MDCTContext {
+ const SampleType *window; ///< MDCT window function
+ FFTContext fft; ///< FFT context for MDCT calculation
+} AC3MDCTContext;
/**
* Data for a single audio block.
int frame_bits; ///< all frame bits except exponents and mantissas
int exponent_bits; ///< number of bits used for exponents
- /* mantissa encoding */
- int mant1_cnt, mant2_cnt, mant4_cnt; ///< mantissa counts for bap=1,2,4
- uint16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
-
SampleType **planar_samples;
uint8_t *bap_buffer;
uint8_t *bap1_buffer;
uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
- DECLARE_ALIGNED(16, SampleType, windowed_samples)[AC3_WINDOW_SIZE];
+ DECLARE_ALIGNED(32, SampleType, windowed_samples)[AC3_WINDOW_SIZE];
} AC3EncodeContext;
+typedef struct AC3Mant {
+ uint16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
+ int mant1_cnt, mant2_cnt, mant4_cnt; ///< mantissa counts for bap=1,2,4
+} AC3Mant;
#define CMIXLEV_NUM_OPTIONS 3
static const float cmixlev_options[CMIXLEV_NUM_OPTIONS] = {
#define OFFSET(param) offsetof(AC3EncodeContext, options.param)
#define AC3ENC_PARAM (AV_OPT_FLAG_AUDIO_PARAM | AV_OPT_FLAG_ENCODING_PARAM)
-static const AVOption options[] = {
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
+const AVOption ff_ac3_options[] = {
/* Metadata Options */
{"per_frame_metadata", "Allow Changing Metadata Per-Frame", OFFSET(allow_per_frame_metadata), FF_OPT_TYPE_INT, 0, 0, 1, AC3ENC_PARAM},
/* downmix levels */
{"hdcd", "HDCD", 0, FF_OPT_TYPE_CONST, 1, INT_MIN, INT_MAX, AC3ENC_PARAM, "ad_conv_type"},
{NULL}
};
+#endif
#if CONFIG_AC3ENC_FLOAT
static AVClass ac3enc_class = { "AC-3 Encoder", av_default_item_name,
- options, LIBAVUTIL_VERSION_INT };
+ ff_ac3_options, LIBAVUTIL_VERSION_INT };
#else
static AVClass ac3enc_class = { "Fixed-Point AC-3 Encoder", av_default_item_name,
- options, LIBAVUTIL_VERSION_INT };
+ ff_ac3_options, LIBAVUTIL_VERSION_INT };
#endif
static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct,
int nbits);
-static void mdct512(AC3MDCTContext *mdct, CoefType *out, SampleType *in);
-
static void apply_window(DSPContext *dsp, SampleType *output, const SampleType *input,
const SampleType *window, unsigned int len);
/**
* List of supported channel layouts.
*/
-static const int64_t ac3_channel_layouts[] = {
+#if CONFIG_AC3ENC_FLOAT || !CONFIG_AC3_FLOAT_ENCODER //we need this exactly once compiled in
+const int64_t ff_ac3_channel_layouts[] = {
AV_CH_LAYOUT_MONO,
AV_CH_LAYOUT_STEREO,
AV_CH_LAYOUT_2_1,
AV_CH_LAYOUT_5POINT1_BACK,
0
};
+#endif
+
+
+/**
+ * LUT to select the bandwidth code based on the bit rate, sample rate, and
+ * number of full-bandwidth channels.
+ * bandwidth_tab[fbw_channels-1][sample rate code][bit rate code]
+ */
+static const uint8_t ac3_bandwidth_tab[5][3][19] = {
+// 32 40 48 56 64 80 96 112 128 160 192 224 256 320 384 448 512 576 640
+
+ { { 0, 0, 0, 12, 16, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
+ { 0, 0, 0, 16, 20, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
+ { 0, 0, 0, 32, 40, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
+
+ { { 0, 0, 0, 0, 0, 0, 0, 20, 24, 32, 48, 48, 48, 48, 48, 48, 48, 48, 48 },
+ { 0, 0, 0, 0, 0, 0, 4, 24, 28, 36, 56, 56, 56, 56, 56, 56, 56, 56, 56 },
+ { 0, 0, 0, 0, 0, 0, 20, 44, 52, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60 } },
+
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 24, 32, 40, 48, 48, 48, 48, 48, 48 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 4, 20, 28, 36, 44, 56, 56, 56, 56, 56, 56 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 20, 40, 48, 60, 60, 60, 60, 60, 60, 60, 60 } },
+
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 32, 48, 48, 48, 48, 48, 48 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 28, 36, 56, 56, 56, 56, 56, 56 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 48, 60, 60, 60, 60, 60, 60, 60 } },
+
+ { { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 20, 32, 40, 48, 48, 48, 48 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 12, 24, 36, 44, 56, 56, 56, 56 },
+ { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 44, 60, 60, 60, 60, 60, 60 } }
+};
/**
/**
* Deinterleave input samples.
- * Channels are reordered from Libav's default order to AC-3 order.
+ * Channels are reordered from FFmpeg's default order to AC-3 order.
*/
static void deinterleave_input_samples(AC3EncodeContext *s,
const SampleType *samples)
block->coeff_shift[ch] = normalize_samples(s);
- mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples);
+ s->mdct.fft.mdct_calcw(&s->mdct.fft, block->mdct_coef[ch],
+ s->windowed_samples);
}
}
}
*/
static void extract_exponents(AC3EncodeContext *s)
{
- int blk, ch, i;
+ int blk, ch;
for (ch = 0; ch < s->channels; ch++) {
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk];
- uint8_t *exp = block->exp[ch];
- int32_t *coef = block->fixed_coef[ch];
- for (i = 0; i < AC3_MAX_COEFS; i++) {
- int e;
- int v = abs(coef[i]);
- if (v == 0)
- e = 24;
- else {
- e = 23 - av_log2(v);
- if (e >= 24) {
- e = 24;
- coef[i] = 0;
- }
- av_assert2(e >= 0);
- }
- exp[i] = e;
- }
+ s->ac3dsp.extract_exponents(block->exp[ch], block->fixed_coef[ch],
+ AC3_MAX_COEFS);
}
}
}
}
-/**
- * Calculate the number of bits needed to encode a set of mantissas.
- */
-static int compute_mantissa_size(int mant_cnt[5], uint8_t *bap, int nb_coefs)
-{
- int bits, b, i;
-
- bits = 0;
- for (i = 0; i < nb_coefs; i++) {
- b = bap[i];
- if (b <= 4) {
- // bap=1 to bap=4 will be counted in compute_mantissa_size_final
- mant_cnt[b]++;
- } else if (b <= 13) {
- // bap=5 to bap=13 use (bap-1) bits
- bits += b - 1;
- } else {
- // bap=14 uses 14 bits and bap=15 uses 16 bits
- bits += (b == 14) ? 14 : 16;
- }
- }
- return bits;
-}
-
-
/**
* Finalize the mantissa bit count by adding in the grouped mantissas.
*/
whenever we reuse exponents. */
block = s->blocks[blk].exp_ref_block[ch];
if (s->exp_strategy[ch][blk] != EXP_REUSE) {
- ff_ac3_bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0,
+ s->ac3dsp.bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0,
s->nb_coefs[ch], snr_offset,
s->bit_alloc.floor, ff_ac3_bap_tab,
block->bap[ch]);
}
- mantissa_bits += compute_mantissa_size(mant_cnt, block->bap[ch], s->nb_coefs[ch]);
+ mantissa_bits += s->ac3dsp.compute_mantissa_size(mant_cnt, block->bap[ch], s->nb_coefs[ch]);
}
mantissa_bits += compute_mantissa_size_final(mant_cnt);
}
*/
static inline int sym_quant(int c, int e, int levels)
{
- int v = ((((levels * c) >> (24 - e)) + 1) >> 1) + (levels >> 1);
+ int v = (((levels * c) >> (24 - e)) + levels) >> 1;
av_assert2(v >= 0 && v < levels);
return v;
}
/**
* Quantize a set of mantissas for a single channel in a single block.
*/
-static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef,
+static void quantize_mantissas_blk_ch(AC3Mant *s, int32_t *fixed_coef,
uint8_t *exp,
uint8_t *bap, uint16_t *qmant, int n)
{
for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
AC3Block *block = &s->blocks[blk];
AC3Block *ref_block;
- s->mant1_cnt = s->mant2_cnt = s->mant4_cnt = 0;
- s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
+ AC3Mant m = { 0 };
for (ch = 0; ch < s->channels; ch++) {
ref_block = block->exp_ref_block[ch];
- quantize_mantissas_blk_ch(s, block->fixed_coef[ch],
+ quantize_mantissas_blk_ch(&m, block->fixed_coef[ch],
ref_block->exp[ch], ref_block->bap[ch],
block->qmant[ch], s->nb_coefs[ch]);
}
bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60);
} else {
/* use default bandwidth setting */
- /* XXX: should compute the bandwidth according to the frame
- size, so that we avoid annoying high frequency artifacts */
- bw_code = 50;
+ bw_code = ac3_bandwidth_tab[s->fbw_channels-1][s->bit_alloc.sr_code][s->frame_size_code/2];
}
/* set number of coefficients for each channel */