1/* 2 * The simplest AC-3 encoder 3 * Copyright (c) 2000 Fabrice Bellard 4 * Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com> 5 * Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de> 6 * 7 * This file is part of FFmpeg. 8 * 9 * FFmpeg is free software; you can redistribute it and/or 10 * modify it under the terms of the GNU Lesser General Public 11 * License as published by the Free Software Foundation; either 12 * version 2.1 of the License, or (at your option) any later version. 13 * 14 * FFmpeg is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with FFmpeg; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 */ 23 24/** 25 * @file 26 * fixed-point AC-3 encoder. 27 */ 28 29#define AC3ENC_FLOAT 0 30#define FFT_FLOAT 0 31#include "audiodsp.h" 32#include "ac3enc.h" 33#include "codec_internal.h" 34#include "eac3enc.h" 35#include "kbdwin.h" 36 37static void sum_square_butterfly(AC3EncodeContext *s, int64_t sum[4], 38 const int32_t *coef0, const int32_t *coef1, 39 int len) 40{ 41 s->ac3dsp.sum_square_butterfly_int32(sum, coef0, coef1, len); 42} 43 44/* 45 * Clip MDCT coefficients to allowable range. 46 */ 47static void clip_coefficients(AudioDSPContext *adsp, int32_t *coef, 48 unsigned int len) 49{ 50 adsp->vector_clip_int32(coef, coef, COEF_MIN, COEF_MAX, len); 51} 52 53 54/* 55 * Calculate a single coupling coordinate. 56 */ 57static CoefType calc_cpl_coord(CoefSumType energy_ch, CoefSumType energy_cpl) 58{ 59 if (energy_cpl <= COEF_MAX) { 60 return 1048576; 61 } else { 62 uint64_t coord = energy_ch / (energy_cpl >> 24); 63 uint32_t coord32 = FFMIN(coord, 1073741824); 64 coord32 = ff_sqrt(coord32) << 9; 65 return FFMIN(coord32, COEF_MAX); 66 } 67} 68 69 70#include "ac3enc_template.c" 71 72 73/** 74 * Finalize MDCT and free allocated memory. 75 * 76 * @param s AC-3 encoder private context 77 */ 78static av_cold void ac3_fixed_mdct_end(AC3EncodeContext *s) 79{ 80 ff_mdct_end(&s->mdct); 81} 82 83/** 84 * Initialize MDCT tables. 85 * 86 * @param s AC-3 encoder private context 87 * @return 0 on success, negative error code on failure 88 */ 89static av_cold int ac3_fixed_mdct_init(AC3EncodeContext *s) 90{ 91 float fwin[AC3_BLOCK_SIZE]; 92 93 int32_t *iwin = av_malloc_array(AC3_BLOCK_SIZE, sizeof(*iwin)); 94 if (!iwin) 95 return AVERROR(ENOMEM); 96 97 ff_kbd_window_init(fwin, 5.0, AC3_BLOCK_SIZE); 98 for (int i = 0; i < AC3_BLOCK_SIZE; i++) 99 iwin[i] = lrintf(fwin[i] * (1 << 22)); 100 101 s->mdct_window = iwin; 102 103 s->fdsp = avpriv_alloc_fixed_dsp(s->avctx->flags & AV_CODEC_FLAG_BITEXACT); 104 if (!s->fdsp) 105 return AVERROR(ENOMEM); 106 107 return ff_mdct_init(&s->mdct, 9, 0, -1.0); 108} 109 110 111static av_cold int ac3_fixed_encode_init(AVCodecContext *avctx) 112{ 113 AC3EncodeContext *s = avctx->priv_data; 114 s->fixed_point = 1; 115 s->mdct_end = ac3_fixed_mdct_end; 116 s->mdct_init = ac3_fixed_mdct_init; 117 s->allocate_sample_buffers = allocate_sample_buffers; 118 return ff_ac3_encode_init(avctx); 119} 120 121 122FF_DISABLE_DEPRECATION_WARNINGS 123const FFCodec ff_ac3_fixed_encoder = { 124 .p.name = "ac3_fixed", 125 .p.long_name = NULL_IF_CONFIG_SMALL("ATSC A/52A (AC-3)"), 126 .p.type = AVMEDIA_TYPE_AUDIO, 127 .p.id = AV_CODEC_ID_AC3, 128 .p.capabilities = AV_CODEC_CAP_DR1, 129 .priv_data_size = sizeof(AC3EncodeContext), 130 .init = ac3_fixed_encode_init, 131 FF_CODEC_ENCODE_CB(ff_ac3_fixed_encode_frame), 132 .close = ff_ac3_encode_close, 133 .p.sample_fmts = (const enum AVSampleFormat[]){ AV_SAMPLE_FMT_S32P, 134 AV_SAMPLE_FMT_NONE }, 135 .p.priv_class = &ff_ac3enc_class, 136 .caps_internal = FF_CODEC_CAP_INIT_THREADSAFE | FF_CODEC_CAP_INIT_CLEANUP, 137 .p.supported_samplerates = ff_ac3_sample_rate_tab, 138#if FF_API_OLD_CHANNEL_LAYOUT 139 .p.channel_layouts = ff_ac3_channel_layouts, 140#endif 141 .p.ch_layouts = ff_ac3_ch_layouts, 142 .defaults = ff_ac3_enc_defaults, 143}; 144FF_ENABLE_DEPRECATION_WARNINGS 145