yading@10: /* yading@10: * The simplest AC-3 encoder yading@10: * Copyright (c) 2000 Fabrice Bellard yading@10: * Copyright (c) 2006-2010 Justin Ruggles yading@10: * Copyright (c) 2006-2010 Prakash Punnoor yading@10: * yading@10: * This file is part of FFmpeg. yading@10: * yading@10: * FFmpeg is free software; you can redistribute it and/or yading@10: * modify it under the terms of the GNU Lesser General Public yading@10: * License as published by the Free Software Foundation; either yading@10: * version 2.1 of the License, or (at your option) any later version. yading@10: * yading@10: * FFmpeg is distributed in the hope that it will be useful, yading@10: * but WITHOUT ANY WARRANTY; without even the implied warranty of yading@10: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU yading@10: * Lesser General Public License for more details. yading@10: * yading@10: * You should have received a copy of the GNU Lesser General Public yading@10: * License along with FFmpeg; if not, write to the Free Software yading@10: * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA yading@10: */ yading@10: yading@10: /** yading@10: * @file yading@10: * fixed-point AC-3 encoder. yading@10: */ yading@10: yading@10: #define CONFIG_FFT_FLOAT 0 yading@10: #undef CONFIG_AC3ENC_FLOAT yading@10: #include "internal.h" yading@10: #include "ac3enc.h" yading@10: #include "eac3enc.h" yading@10: yading@10: #define AC3ENC_TYPE AC3ENC_TYPE_AC3_FIXED yading@10: #include "ac3enc_opts_template.c" yading@10: yading@10: static const AVClass ac3enc_class = { yading@10: .class_name = "Fixed-Point AC-3 Encoder", yading@10: .item_name = av_default_item_name, yading@10: .option = ac3_options, yading@10: .version = LIBAVUTIL_VERSION_INT, yading@10: }; yading@10: yading@10: #include "ac3enc_template.c" yading@10: yading@10: yading@10: /** yading@10: * Finalize MDCT and free allocated memory. yading@10: * yading@10: * @param s AC-3 encoder private context yading@10: */ yading@10: av_cold void AC3_NAME(mdct_end)(AC3EncodeContext *s) yading@10: { yading@10: ff_mdct_end(&s->mdct); yading@10: } yading@10: yading@10: yading@10: /** yading@10: * Initialize MDCT tables. yading@10: * yading@10: * @param s AC-3 encoder private context yading@10: * @return 0 on success, negative error code on failure yading@10: */ yading@10: av_cold int AC3_NAME(mdct_init)(AC3EncodeContext *s) yading@10: { yading@10: int ret = ff_mdct_init(&s->mdct, 9, 0, -1.0); yading@10: s->mdct_window = ff_ac3_window; yading@10: return ret; yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Apply KBD window to input samples prior to MDCT. yading@10: */ yading@10: static void apply_window(void *dsp, int16_t *output, const int16_t *input, yading@10: const int16_t *window, unsigned int len) yading@10: { yading@10: DSPContext *dsp0 = dsp; yading@10: dsp0->apply_window_int16(output, input, window, len); yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Normalize the input samples to use the maximum available precision. yading@10: * This assumes signed 16-bit input samples. yading@10: */ yading@10: static int normalize_samples(AC3EncodeContext *s) yading@10: { yading@10: int v = s->ac3dsp.ac3_max_msb_abs_int16(s->windowed_samples, AC3_WINDOW_SIZE); yading@10: v = 14 - av_log2(v); yading@10: if (v > 0) yading@10: s->ac3dsp.ac3_lshift_int16(s->windowed_samples, AC3_WINDOW_SIZE, v); yading@10: /* +6 to right-shift from 31-bit to 25-bit */ yading@10: return v + 6; yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Scale MDCT coefficients to 25-bit signed fixed-point. yading@10: */ yading@10: static void scale_coefficients(AC3EncodeContext *s) yading@10: { yading@10: int blk, ch; yading@10: yading@10: for (blk = 0; blk < s->num_blocks; blk++) { yading@10: AC3Block *block = &s->blocks[blk]; yading@10: for (ch = 1; ch <= s->channels; ch++) { yading@10: s->ac3dsp.ac3_rshift_int32(block->mdct_coef[ch], AC3_MAX_COEFS, yading@10: block->coeff_shift[ch]); yading@10: } yading@10: } yading@10: } yading@10: yading@10: static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], yading@10: const int32_t *coef0, const int32_t *coef1, yading@10: int len) yading@10: { yading@10: s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len); yading@10: } yading@10: yading@10: /* yading@10: * Clip MDCT coefficients to allowable range. yading@10: */ yading@10: static void clip_coefficients(DSPContext *dsp, int32_t *coef, unsigned int len) yading@10: { yading@10: dsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len); yading@10: } yading@10: yading@10: yading@10: /* yading@10: * Calculate a single coupling coordinate. yading@10: */ yading@10: static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) yading@10: { yading@10: if (energy_cpl <= COEF_MAX) { yading@10: return 1048576; yading@10: } else { yading@10: uint64_t coord = energy_ch / (energy_cpl >> 24); yading@10: uint32_t coord32 = FFMIN(coord, 1073741824); yading@10: coord32 = ff_sqrt(coord32) << 9; yading@10: return FFMIN(coord32, COEF_MAX); yading@10: } yading@10: } yading@10: yading@10: yading@10: static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) yading@10: { yading@10: AC3EncodeContext *s = avctx->priv_data; yading@10: s->fixed_point = 1; yading@10: return ff_ac3_encode_init(avctx); yading@10: } yading@10: yading@10: yading@10: AVCodec ff_ac3_fixed_encoder = { yading@10: .name = "ac3_fixed", yading@10: .type = AVMEDIA_TYPE_AUDIO, yading@10: .id = AV_CODEC_ID_AC3, yading@10: .priv_data_size = sizeof(AC3EncodeContext), yading@10: .init = ac3_fixed_encode_init, yading@10: .encode2 = ff_ac3_fixed_encode_frame, yading@10: .close = ff_ac3_encode_close, yading@10: .sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S16P, yading@10: AV_SAMPLE_FMT_NONE }, yading@10: .long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), yading@10: .priv_class = &ac3enc_class, yading@10: .channel_layouts = ff_ac3_channel_layouts, yading@10: .defaults = ac3_defaults, yading@10: };