## ffmpeg / libavcodec / ac3enc.c @ 85ab2904

History | View | Annotate | Download (58.1 KB)

1 | de6d9b64 | Fabrice Bellard | ```
/*
``` |
---|---|---|---|

2 | 14b70628 | Justin Ruggles | ```
* The simplest AC-3 encoder
``` |

3 | 406792e7 | Diego Biurrun | ```
* Copyright (c) 2000 Fabrice Bellard
``` |

4 | 27af78cf | Justin Ruggles | ```
* Copyright (c) 2006-2010 Justin Ruggles <justin.ruggles@gmail.com>
``` |

5 | ```
* Copyright (c) 2006-2010 Prakash Punnoor <prakash@punnoor.de>
``` |
||

6 | de6d9b64 | Fabrice Bellard | ```
*
``` |

7 | 2912e87a | Mans Rullgard | ```
* This file is part of Libav.
``` |

8 | b78e7197 | Diego Biurrun | ```
*
``` |

9 | 2912e87a | Mans Rullgard | ```
* Libav is free software; you can redistribute it and/or
``` |

10 | ff4ec49e | Fabrice Bellard | ```
* modify it under the terms of the GNU Lesser General Public
``` |

11 | ```
* License as published by the Free Software Foundation; either
``` |
||

12 | b78e7197 | Diego Biurrun | ```
* version 2.1 of the License, or (at your option) any later version.
``` |

13 | de6d9b64 | Fabrice Bellard | ```
*
``` |

14 | 2912e87a | Mans Rullgard | ```
* Libav is distributed in the hope that it will be useful,
``` |

15 | de6d9b64 | Fabrice Bellard | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |

16 | ff4ec49e | Fabrice Bellard | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |

17 | ```
* Lesser General Public License for more details.
``` |
||

18 | de6d9b64 | Fabrice Bellard | ```
*
``` |

19 | ff4ec49e | Fabrice Bellard | ```
* You should have received a copy of the GNU Lesser General Public
``` |

20 | 2912e87a | Mans Rullgard | ```
* License along with Libav; if not, write to the Free Software
``` |

21 | 5509bffa | Diego Biurrun | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |

22 | de6d9b64 | Fabrice Bellard | ```
*/
``` |

23 | 983e3246 | Michael Niedermayer | |

24 | ```
/**
``` |
||

25 | ba87f080 | Diego Biurrun | ```
* @file
``` |

26 | 14b70628 | Justin Ruggles | ```
* The simplest AC-3 encoder.
``` |

27 | 983e3246 | Michael Niedermayer | ```
*/
``` |

28 | 6a988808 | Justin Ruggles | |

29 | 1a565432 | Fabrice Bellard | ```
//#define DEBUG
``` |

30 | 7100d63c | Justin Ruggles | ```
//#define ASSERT_LEVEL 2
``` |

31 | 22c0b03c | Justin Ruggles | |

32 | 737eb597 | Reinhard Tartler | #include "libavutil/audioconvert.h" |

33 | 7100d63c | Justin Ruggles | #include "libavutil/avassert.h" |

34 | 245976da | Diego Biurrun | #include "libavutil/crc.h" |

35 | de6d9b64 | Fabrice Bellard | #include "avcodec.h" |

36 | b2755007 | Stefano Sabatini | #include "put_bits.h" |

37 | 8846ee54 | Justin Ruggles | #include "dsputil.h" |

38 | dda3f0ef | Justin Ruggles | #include "ac3dsp.h" |

39 | 6107fa87 | Fabrice Bellard | #include "ac3.h" |

40 | 120b4557 | Justin Ruggles | #include "audioconvert.h" |

41 | 6107fa87 | Fabrice Bellard | |

42 | 2f8ae522 | Justin Ruggles | |

43 | 6fd96d1a | Justin Ruggles | ```
#ifndef CONFIG_AC3ENC_FLOAT
``` |

44 | #define CONFIG_AC3ENC_FLOAT 0 |
||

45 | ```
#endif
``` |
||

46 | |||

47 | |||

48 | f94bacc5 | Justin Ruggles | ```
/** Maximum number of exponent groups. +1 for separate DC exponent. */
``` |

49 | #define AC3_MAX_EXP_GROUPS 85 |
||

50 | |||

51 | dc7e07ac | Justin Ruggles | ```
/* stereo rematrixing algorithms */
``` |

52 | #define AC3_REMATRIXING_IS_STATIC 0x1 |
||

53 | #define AC3_REMATRIXING_SUMS 0 |
||

54 | #define AC3_REMATRIXING_NONE 1 |
||

55 | #define AC3_REMATRIXING_ALWAYS 3 |
||

56 | |||

57 | c36ce0f8 | Justin Ruggles | ```
/** Scale a float value by 2^bits and convert to an integer. */
``` |

58 | 918cd225 | Justin Ruggles | #define SCALE_FLOAT(a, bits) lrintf((a) * (float)(1 << (bits))) |

59 | |||

60 | 0cbd5ff7 | Justin Ruggles | |

61 | 6fd96d1a | Justin Ruggles | ```
#if CONFIG_AC3ENC_FLOAT
``` |

62 | #include "ac3enc_float.h" |
||

63 | ```
#else
``` |
||

64 | ad6b2c1f | Justin Ruggles | #include "ac3enc_fixed.h" |

65 | 6fd96d1a | Justin Ruggles | ```
#endif
``` |

66 | e77fd066 | Justin Ruggles | |

67 | 2f8ae522 | Justin Ruggles | |

68 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

69 | 5901cebe | Justin Ruggles | ```
* Data for a single audio block.
``` |

70 | ```
*/
``` |
||

71 | typedef struct AC3Block { |
||

72 | b6f6204d | Justin Ruggles | ```
uint8_t **bap; ///< bit allocation pointers (bap)
``` |

73 | 0cbd5ff7 | Justin Ruggles | ```
CoefType **mdct_coef; ///< MDCT coefficients
``` |

74 | ac05f903 | Justin Ruggles | ```
int32_t **fixed_coef; ///< fixed-point MDCT coefficients
``` |

75 | b6f6204d | Justin Ruggles | ```
uint8_t **exp; ///< original exponents
``` |

76 | ```
uint8_t **grouped_exp; ///< grouped exponents
``` |
||

77 | ```
int16_t **psd; ///< psd per frequency bin
``` |
||

78 | ```
int16_t **band_psd; ///< psd per critical band
``` |
||

79 | ```
int16_t **mask; ///< masking curve
``` |
||

80 | ```
uint16_t **qmant; ///< quantized mantissas
``` |
||

81 | 323e6fea | Justin | ```
uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values
``` |

82 | dc7e07ac | Justin Ruggles | ```
uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block
``` |

83 | uint8_t rematrixing_flags[4]; ///< rematrixing flags |
||

84 | 5901cebe | Justin Ruggles | } AC3Block; |

85 | |||

86 | ```
/**
``` |
||

87 | c36ce0f8 | Justin Ruggles | ```
* AC-3 encoder private context.
``` |

88 | ```
*/
``` |
||

89 | 6107fa87 | Fabrice Bellard | typedef struct AC3EncodeContext { |

90 | 07965463 | Justin Ruggles | ```
PutBitContext pb; ///< bitstream writer context
``` |

91 | 8846ee54 | Justin Ruggles | DSPContext dsp; |

92 | dda3f0ef | Justin Ruggles | ```
AC3DSPContext ac3dsp; ///< AC-3 optimized functions
``` |

93 | c41ac4f8 | Justin Ruggles | ```
AC3MDCTContext mdct; ///< MDCT context
``` |

94 | 7e5a4bf8 | Justin Ruggles | |

95 | 5901cebe | Justin Ruggles | ```
AC3Block blocks[AC3_MAX_BLOCKS]; ///< per-block info
``` |

96 | |||

97 | 07965463 | Justin Ruggles | int bitstream_id; ///< bitstream id (bsid) |

98 | int bitstream_mode; ///< bitstream mode (bsmod) |
||

99 | 7e5a4bf8 | Justin Ruggles | |

100 | 07965463 | Justin Ruggles | int bit_rate; ///< target bit rate, in bits-per-second |

101 | int sample_rate; ///< sampling frequency, in Hz |
||

102 | 7e5a4bf8 | Justin Ruggles | |

103 | 07965463 | Justin Ruggles | int frame_size_min; ///< minimum frame size in case rounding is necessary |

104 | 427e2293 | Justin Ruggles | int frame_size; ///< current frame size in bytes |

105 | 07965463 | Justin Ruggles | int frame_size_code; ///< frame size code (frmsizecod) |

106 | a81d7c6a | Justin Ruggles | ```
uint16_t crc_inv[2];
``` |

107 | 07965463 | Justin Ruggles | int bits_written; ///< bit count (used to avg. bitrate) |

108 | int samples_written; ///< sample count (used to avg. bitrate) |
||

109 | 7e5a4bf8 | Justin Ruggles | |

110 | 07965463 | Justin Ruggles | int fbw_channels; ///< number of full-bandwidth channels (nfchans) |

111 | int channels; ///< total number of channels (nchans) |
||

112 | int lfe_on; ///< indicates if there is an LFE channel (lfeon) |
||

113 | int lfe_channel; ///< channel index of the LFE channel |
||

114 | int channel_mode; ///< channel mode (acmod) |
||

115 | const uint8_t *channel_map; ///< channel map used to reorder channels |
||

116 | 7e5a4bf8 | Justin Ruggles | |

117 | e62ef8f2 | Justin Ruggles | int cutoff; ///< user-specified cutoff frequency, in Hz |

118 | 07965463 | Justin Ruggles | int bandwidth_code[AC3_MAX_CHANNELS]; ///< bandwidth code (0 to 60) (chbwcod) |

119 | 6107fa87 | Fabrice Bellard | ```
int nb_coefs[AC3_MAX_CHANNELS];
``` |

120 | 115329f1 | Diego Biurrun | |

121 | dc7e07ac | Justin Ruggles | int rematrixing; ///< determines how rematrixing strategy is calculated |

122 | 53e35fd3 | Justin Ruggles | int num_rematrixing_bands; ///< number of rematrixing bands |

123 | dc7e07ac | Justin Ruggles | |

124 | 6107fa87 | Fabrice Bellard | ```
/* bitrate allocation control */
``` |

125 | 07965463 | Justin Ruggles | int slow_gain_code; ///< slow gain code (sgaincod) |

126 | int slow_decay_code; ///< slow decay code (sdcycod) |
||

127 | int fast_decay_code; ///< fast decay code (fdcycod) |
||

128 | int db_per_bit_code; ///< dB/bit code (dbpbcod) |
||

129 | int floor_code; ///< floor code (floorcod) |
||

130 | ```
AC3BitAllocParameters bit_alloc; ///< bit allocation parameters
``` |
||

131 | int coarse_snr_offset; ///< coarse SNR offsets (csnroffst) |
||

132 | int fast_gain_code[AC3_MAX_CHANNELS]; ///< fast gain codes (signal-to-mask ratio) (fgaincod) |
||

133 | int fine_snr_offset[AC3_MAX_CHANNELS]; ///< fine SNR offsets (fsnroffst) |
||

134 | e7536ac5 | Justin Ruggles | int frame_bits_fixed; ///< number of non-coefficient bits for fixed parameters |

135 | 359c1d19 | Justin Ruggles | int frame_bits; ///< all frame bits except exponents and mantissas |

136 | int exponent_bits; ///< number of bits used for exponents |
||

137 | 7e5a4bf8 | Justin Ruggles | |

138 | 6107fa87 | Fabrice Bellard | ```
/* mantissa encoding */
``` |

139 | 07965463 | Justin Ruggles | int mant1_cnt, mant2_cnt, mant4_cnt; ///< mantissa counts for bap=1,2,4 |

140 | b6a1e523 | Justin Ruggles | ```
uint16_t *qmant1_ptr, *qmant2_ptr, *qmant4_ptr; ///< mantissa pointers for bap=1,2,4
``` |

141 | 7e5a4bf8 | Justin Ruggles | |

142 | c05ffcd9 | Justin Ruggles | SampleType **planar_samples; |

143 | 171bc51c | Justin Ruggles | uint8_t *bap_buffer; |

144 | uint8_t *bap1_buffer; |
||

145 | 0cbd5ff7 | Justin Ruggles | CoefType *mdct_coef_buffer; |

146 | ac05f903 | Justin Ruggles | int32_t *fixed_coef_buffer; |

147 | b6f6204d | Justin Ruggles | uint8_t *exp_buffer; |

148 | uint8_t *grouped_exp_buffer; |
||

149 | int16_t *psd_buffer; |
||

150 | int16_t *band_psd_buffer; |
||

151 | int16_t *mask_buffer; |
||

152 | uint16_t *qmant_buffer; |
||

153 | aa645b98 | Justin Ruggles | |

154 | 0429e4a6 | Justin Ruggles | ```
uint8_t exp_strategy[AC3_MAX_CHANNELS][AC3_MAX_BLOCKS]; ///< exponent strategies
``` |

155 | |||

156 | 0cbd5ff7 | Justin Ruggles | ```
DECLARE_ALIGNED(16, SampleType, windowed_samples)[AC3_WINDOW_SIZE];
``` |

157 | 6107fa87 | Fabrice Bellard | } AC3EncodeContext; |

158 | de6d9b64 | Fabrice Bellard | |

159 | 2f8ae522 | Justin Ruggles | |

160 | f1cbbb79 | Justin Ruggles | ```
/* prototypes for functions in ac3enc_fixed.c and ac3enc_float.c */
``` |

161 | ad6b2c1f | Justin Ruggles | |

162 | static av_cold void mdct_end(AC3MDCTContext *mdct); |
||

163 | |||

164 | static av_cold int mdct_init(AVCodecContext *avctx, AC3MDCTContext *mdct, |
||

165 | ```
int nbits);
``` |
||

166 | |||

167 | static void mdct512(AC3MDCTContext *mdct, CoefType *out, SampleType *in); |
||

168 | |||

169 | 3b924294 | Justin Ruggles | static void apply_window(DSPContext *dsp, SampleType *output, const SampleType *input, |

170 | ad6b2c1f | Justin Ruggles | const SampleType *window, int n); |

171 | |||

172 | static int normalize_samples(AC3EncodeContext *s); |
||

173 | |||

174 | ac05f903 | Justin Ruggles | static void scale_coefficients(AC3EncodeContext *s); |

175 | |||

176 | ad6b2c1f | Justin Ruggles | |

177 | e86ea34d | Justin Ruggles | ```
/**
``` |

178 | ```
* LUT for number of exponent groups.
``` |
||

179 | ```
* exponent_group_tab[exponent strategy-1][number of coefficients]
``` |
||

180 | ```
*/
``` |
||

181 | e0698e4b | Justin Ruggles | static uint8_t exponent_group_tab[3][256]; |

182 | e86ea34d | Justin Ruggles | |

183 | 2f8ae522 | Justin Ruggles | |

184 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

185 | b33dae5e | Justin Ruggles | ```
* List of supported channel layouts.
``` |

186 | ```
*/
``` |
||

187 | static const int64_t ac3_channel_layouts[] = { |
||

188 | AV_CH_LAYOUT_MONO, |
||

189 | AV_CH_LAYOUT_STEREO, |
||

190 | AV_CH_LAYOUT_2_1, |
||

191 | AV_CH_LAYOUT_SURROUND, |
||

192 | AV_CH_LAYOUT_2_2, |
||

193 | AV_CH_LAYOUT_QUAD, |
||

194 | AV_CH_LAYOUT_4POINT0, |
||

195 | AV_CH_LAYOUT_5POINT0, |
||

196 | AV_CH_LAYOUT_5POINT0_BACK, |
||

197 | (AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY), |
||

198 | (AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY), |
||

199 | (AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY), |
||

200 | (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY), |
||

201 | (AV_CH_LAYOUT_2_2 | AV_CH_LOW_FREQUENCY), |
||

202 | (AV_CH_LAYOUT_QUAD | AV_CH_LOW_FREQUENCY), |
||

203 | (AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY), |
||

204 | AV_CH_LAYOUT_5POINT1, |
||

205 | AV_CH_LAYOUT_5POINT1_BACK, |
||

206 | ```
0
``` |
||

207 | }; |
||

208 | |||

209 | |||

210 | ```
/**
``` |
||

211 | 160d85f5 | Justin Ruggles | ```
* Adjust the frame size to make the average bit rate match the target bit rate.
``` |

212 | ```
* This is only needed for 11025, 22050, and 44100 sample rates.
``` |
||

213 | ```
*/
``` |
||

214 | static void adjust_frame_size(AC3EncodeContext *s) |
||

215 | { |
||

216 | ```
while (s->bits_written >= s->bit_rate && s->samples_written >= s->sample_rate) {
``` |
||

217 | s->bits_written -= s->bit_rate; |
||

218 | s->samples_written -= s->sample_rate; |
||

219 | } |
||

220 | 2d82d9b1 | Justin Ruggles | s->frame_size = s->frame_size_min + |

221 | ```
2 * (s->bits_written * s->sample_rate < s->samples_written * s->bit_rate);
``` |
||

222 | 160d85f5 | Justin Ruggles | ```
s->bits_written += s->frame_size * 8;
``` |

223 | s->samples_written += AC3_FRAME_SIZE; |
||

224 | } |
||

225 | |||

226 | |||

227 | ```
/**
``` |
||

228 | 4acc790f | Justin Ruggles | ```
* Deinterleave input samples.
``` |

229 | 2912e87a | Mans Rullgard | ```
* Channels are reordered from Libav's default order to AC-3 order.
``` |

230 | 4acc790f | Justin Ruggles | ```
*/
``` |

231 | static void deinterleave_input_samples(AC3EncodeContext *s, |
||

232 | 0cbd5ff7 | Justin Ruggles | ```
const SampleType *samples)
``` |

233 | 4acc790f | Justin Ruggles | { |

234 | ```
int ch, i;
``` |
||

235 | |||

236 | ```
/* deinterleave and remap input samples */
``` |
||

237 | for (ch = 0; ch < s->channels; ch++) { |
||

238 | 0cbd5ff7 | Justin Ruggles | ```
const SampleType *sptr;
``` |

239 | 4acc790f | Justin Ruggles | ```
int sinc;
``` |

240 | |||

241 | ```
/* copy last 256 samples of previous frame to the start of the current frame */
``` |
||

242 | 1c3e117e | Justin Ruggles | ```
memcpy(&s->planar_samples[ch][0], &s->planar_samples[ch][AC3_FRAME_SIZE],
``` |

243 | 266d24be | Justin Ruggles | AC3_BLOCK_SIZE * sizeof(s->planar_samples[0][0])); |

244 | 4acc790f | Justin Ruggles | |

245 | ```
/* deinterleave */
``` |
||

246 | sinc = s->channels; |
||

247 | sptr = samples + s->channel_map[ch]; |
||

248 | ```
for (i = AC3_BLOCK_SIZE; i < AC3_FRAME_SIZE+AC3_BLOCK_SIZE; i++) {
``` |
||

249 | 266d24be | Justin Ruggles | s->planar_samples[ch][i] = *sptr; |

250 | 4acc790f | Justin Ruggles | sptr += sinc; |

251 | } |
||

252 | } |
||

253 | } |
||

254 | |||

255 | |||

256 | ```
/**
``` |
||

257 | 0a0a8500 | Justin Ruggles | ```
* Apply the MDCT to input samples to generate frequency coefficients.
``` |

258 | ```
* This applies the KBD window and normalizes the input to reduce precision
``` |
||

259 | ```
* loss due to fixed-point calculations.
``` |
||

260 | ```
*/
``` |
||

261 | 266d24be | Justin Ruggles | static void apply_mdct(AC3EncodeContext *s) |

262 | 0a0a8500 | Justin Ruggles | { |

263 | ```
int blk, ch;
``` |
||

264 | |||

265 | for (ch = 0; ch < s->channels; ch++) { |
||

266 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

267 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

268 | 0cbd5ff7 | Justin Ruggles | ```
const SampleType *input_samples = &s->planar_samples[ch][blk * AC3_BLOCK_SIZE];
``` |

269 | 0a0a8500 | Justin Ruggles | |

270 | 3b924294 | Justin Ruggles | apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE); |

271 | 0a0a8500 | Justin Ruggles | |

272 | 323e6fea | Justin | block->coeff_shift[ch] = normalize_samples(s); |

273 | 0a0a8500 | Justin Ruggles | |

274 | c41ac4f8 | Justin Ruggles | mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples); |

275 | 0a0a8500 | Justin Ruggles | } |

276 | } |
||

277 | } |
||

278 | |||

279 | |||

280 | ```
/**
``` |
||

281 | dc7e07ac | Justin Ruggles | ```
* Initialize stereo rematrixing.
``` |

282 | ```
* If the strategy does not change for each frame, set the rematrixing flags.
``` |
||

283 | ```
*/
``` |
||

284 | static void rematrixing_init(AC3EncodeContext *s) |
||

285 | { |
||

286 | ```
if (s->channel_mode == AC3_CHMODE_STEREO)
``` |
||

287 | s->rematrixing = AC3_REMATRIXING_SUMS; |
||

288 | ```
else
``` |
||

289 | s->rematrixing = AC3_REMATRIXING_NONE; |
||

290 | ```
/* NOTE: AC3_REMATRIXING_ALWAYS might be used in
``` |
||

291 | ```
the future in conjunction with channel coupling. */
``` |
||

292 | |||

293 | ```
if (s->rematrixing & AC3_REMATRIXING_IS_STATIC) {
``` |
||

294 | ```
int flag = (s->rematrixing == AC3_REMATRIXING_ALWAYS);
``` |
||

295 | s->blocks[0].new_rematrixing_strategy = 1; |
||

296 | ```
memset(s->blocks[0].rematrixing_flags, flag,
``` |
||

297 | sizeof(s->blocks[0].rematrixing_flags)); |
||

298 | } |
||

299 | } |
||

300 | |||

301 | |||

302 | ```
/**
``` |
||

303 | ```
* Determine rematrixing flags for each block and band.
``` |
||

304 | ```
*/
``` |
||

305 | static void compute_rematrixing_strategy(AC3EncodeContext *s) |
||

306 | { |
||

307 | ```
int nb_coefs;
``` |
||

308 | ```
int blk, bnd, i;
``` |
||

309 | AC3Block *block, *block0; |
||

310 | |||

311 | 53e35fd3 | Justin Ruggles | ```
s->num_rematrixing_bands = 4;
``` |

312 | |||

313 | dc7e07ac | Justin Ruggles | ```
if (s->rematrixing & AC3_REMATRIXING_IS_STATIC)
``` |

314 | ```
return;
``` |
||

315 | |||

316 | nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); |
||

317 | |||

318 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

319 | block = &s->blocks[blk]; |
||

320 | 5b54d4b3 | Justin Ruggles | block->new_rematrixing_strategy = !blk; |

321 | 53e35fd3 | Justin Ruggles | for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { |

322 | dc7e07ac | Justin Ruggles | ```
/* calculate calculate sum of squared coeffs for one band in one block */
``` |

323 | ```
int start = ff_ac3_rematrix_band_tab[bnd];
``` |
||

324 | int end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]); |
||

325 | CoefSumType sum[4] = {0,}; |
||

326 | ```
for (i = start; i < end; i++) {
``` |
||

327 | ```
CoefType lt = block->mdct_coef[0][i];
``` |
||

328 | ```
CoefType rt = block->mdct_coef[1][i];
``` |
||

329 | CoefType md = lt + rt; |
||

330 | CoefType sd = lt - rt; |
||

331 | 323e6fea | Justin | ```
MAC_COEF(sum[0], lt, lt);
``` |

332 | ```
MAC_COEF(sum[1], rt, rt);
``` |
||

333 | ```
MAC_COEF(sum[2], md, md);
``` |
||

334 | ```
MAC_COEF(sum[3], sd, sd);
``` |
||

335 | dc7e07ac | Justin Ruggles | } |

336 | |||

337 | ```
/* compare sums to determine if rematrixing will be used for this band */
``` |
||

338 | if (FFMIN(sum[2], sum[3]) < FFMIN(sum[0], sum[1])) |
||

339 | ```
block->rematrixing_flags[bnd] = 1;
``` |
||

340 | ```
else
``` |
||

341 | ```
block->rematrixing_flags[bnd] = 0;
``` |
||

342 | |||

343 | ```
/* determine if new rematrixing flags will be sent */
``` |
||

344 | ```
if (blk &&
``` |
||

345 | block->rematrixing_flags[bnd] != block0->rematrixing_flags[bnd]) { |
||

346 | ```
block->new_rematrixing_strategy = 1;
``` |
||

347 | } |
||

348 | } |
||

349 | block0 = block; |
||

350 | } |
||

351 | } |
||

352 | |||

353 | |||

354 | ```
/**
``` |
||

355 | ```
* Apply stereo rematrixing to coefficients based on rematrixing flags.
``` |
||

356 | ```
*/
``` |
||

357 | static void apply_rematrixing(AC3EncodeContext *s) |
||

358 | { |
||

359 | ```
int nb_coefs;
``` |
||

360 | ```
int blk, bnd, i;
``` |
||

361 | ```
int start, end;
``` |
||

362 | uint8_t *flags; |
||

363 | |||

364 | ```
if (s->rematrixing == AC3_REMATRIXING_NONE)
``` |
||

365 | ```
return;
``` |
||

366 | |||

367 | nb_coefs = FFMIN(s->nb_coefs[0], s->nb_coefs[1]); |
||

368 | |||

369 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

370 | AC3Block *block = &s->blocks[blk]; |
||

371 | ```
if (block->new_rematrixing_strategy)
``` |
||

372 | flags = block->rematrixing_flags; |
||

373 | 53e35fd3 | Justin Ruggles | for (bnd = 0; bnd < s->num_rematrixing_bands; bnd++) { |

374 | dc7e07ac | Justin Ruggles | ```
if (flags[bnd]) {
``` |

375 | start = ff_ac3_rematrix_band_tab[bnd]; |
||

376 | ```
end = FFMIN(nb_coefs, ff_ac3_rematrix_band_tab[bnd+1]);
``` |
||

377 | ```
for (i = start; i < end; i++) {
``` |
||

378 | ```
int32_t lt = block->fixed_coef[0][i];
``` |
||

379 | ```
int32_t rt = block->fixed_coef[1][i];
``` |
||

380 | block->fixed_coef[0][i] = (lt + rt) >> 1; |
||

381 | block->fixed_coef[1][i] = (lt - rt) >> 1; |
||

382 | } |
||

383 | } |
||

384 | } |
||

385 | } |
||

386 | } |
||

387 | |||

388 | |||

389 | ```
/**
``` |
||

390 | e86ea34d | Justin Ruggles | ```
* Initialize exponent tables.
``` |

391 | ```
*/
``` |
||

392 | static av_cold void exponent_init(AC3EncodeContext *s) |
||

393 | { |
||

394 | ```
int i;
``` |
||

395 | for (i = 73; i < 256; i++) { |
||

396 | exponent_group_tab[0][i] = (i - 1) / 3; |
||

397 | exponent_group_tab[1][i] = (i + 2) / 6; |
||

398 | exponent_group_tab[2][i] = (i + 8) / 12; |
||

399 | } |
||

400 | 78646ac2 | Justin Ruggles | ```
/* LFE */
``` |

401 | exponent_group_tab[0][7] = 2; |
||

402 | e86ea34d | Justin Ruggles | } |

403 | |||

404 | |||

405 | ```
/**
``` |
||

406 | dfdf73eb | Justin Ruggles | ```
* Extract exponents from the MDCT coefficients.
``` |

407 | ```
* This takes into account the normalization that was done to the input samples
``` |
||

408 | ```
* by adjusting the exponents by the exponent shift values.
``` |
||

409 | ```
*/
``` |
||

410 | 266d24be | Justin Ruggles | static void extract_exponents(AC3EncodeContext *s) |

411 | dfdf73eb | Justin Ruggles | { |

412 | ```
int blk, ch, i;
``` |
||

413 | |||

414 | for (ch = 0; ch < s->channels; ch++) { |
||

415 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

416 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

417 | 9be52d48 | Justin Ruggles | uint8_t *exp = block->exp[ch]; |

418 | ac05f903 | Justin Ruggles | int32_t *coef = block->fixed_coef[ch]; |

419 | dfdf73eb | Justin Ruggles | for (i = 0; i < AC3_MAX_COEFS; i++) { |

420 | ```
int e;
``` |
||

421 | ac05f903 | Justin Ruggles | ```
int v = abs(coef[i]);
``` |

422 | dfdf73eb | Justin Ruggles | if (v == 0) |

423 | ```
e = 24;
``` |
||

424 | ```
else {
``` |
||

425 | 323e6fea | Justin | ```
e = 23 - av_log2(v);
``` |

426 | dfdf73eb | Justin Ruggles | if (e >= 24) { |

427 | ```
e = 24;
``` |
||

428 | 9be52d48 | Justin Ruggles | ```
coef[i] = 0;
``` |

429 | dfdf73eb | Justin Ruggles | } |

430 | 2d9a101a | Justin Ruggles | ```
av_assert2(e >= 0);
``` |

431 | dfdf73eb | Justin Ruggles | } |

432 | 9be52d48 | Justin Ruggles | exp[i] = e; |

433 | dfdf73eb | Justin Ruggles | } |

434 | } |
||

435 | } |
||

436 | } |
||

437 | |||

438 | |||

439 | ```
/**
``` |
||

440 | c36ce0f8 | Justin Ruggles | ```
* Exponent Difference Threshold.
``` |

441 | ```
* New exponents are sent if their SAD exceed this number.
``` |
||

442 | ```
*/
``` |
||

443 | c3beafa0 | Justin Ruggles | #define EXP_DIFF_THRESHOLD 500 |

444 | 6a988808 | Justin Ruggles | |

445 | 2f8ae522 | Justin Ruggles | |

446 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

447 | ```
* Calculate exponent strategies for all blocks in a single channel.
``` |
||

448 | ```
*/
``` |
||

449 | b5293036 | Justin Ruggles | static void compute_exp_strategy_ch(AC3EncodeContext *s, uint8_t *exp_strategy, |

450 | 5bff8590 | Justin Ruggles | uint8_t *exp) |

451 | de6d9b64 | Fabrice Bellard | { |

452 | ce67b7cd | Justin Ruggles | ```
int blk, blk1;
``` |

453 | de6d9b64 | Fabrice Bellard | ```
int exp_diff;
``` |

454 | 115329f1 | Diego Biurrun | |

455 | de6d9b64 | Fabrice Bellard | ```
/* estimate if the exponent variation & decide if they should be
``` |

456 | ```
reused in the next frame */
``` |
||

457 | d7da8080 | Justin Ruggles | ```
exp_strategy[0] = EXP_NEW;
``` |

458 | 5bff8590 | Justin Ruggles | exp += AC3_MAX_COEFS; |

459 | ce67b7cd | Justin Ruggles | for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) { |

460 | 5bff8590 | Justin Ruggles | exp_diff = s->dsp.sad[0](NULL, exp, exp - AC3_MAX_COEFS, 16, 16); |

461 | de6d9b64 | Fabrice Bellard | ```
if (exp_diff > EXP_DIFF_THRESHOLD)
``` |

462 | d7da8080 | Justin Ruggles | exp_strategy[blk] = EXP_NEW; |

463 | de6d9b64 | Fabrice Bellard | ```
else
``` |

464 | d7da8080 | Justin Ruggles | exp_strategy[blk] = EXP_REUSE; |

465 | 5bff8590 | Justin Ruggles | exp += AC3_MAX_COEFS; |

466 | de6d9b64 | Fabrice Bellard | } |

467 | 30b68f33 | Zdenek Kabelac | |

468 | de6d9b64 | Fabrice Bellard | ```
/* now select the encoding strategy type : if exponents are often
``` |

469 | ```
recoded, we use a coarse encoding */
``` |
||

470 | ce67b7cd | Justin Ruggles | ```
blk = 0;
``` |

471 | ```
while (blk < AC3_MAX_BLOCKS) {
``` |
||

472 | ```
blk1 = blk + 1;
``` |
||

473 | d7da8080 | Justin Ruggles | ```
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE)
``` |

474 | ce67b7cd | Justin Ruggles | blk1++; |

475 | ```
switch (blk1 - blk) {
``` |
||

476 | d7da8080 | Justin Ruggles | case 1: exp_strategy[blk] = EXP_D45; break; |

477 | de6d9b64 | Fabrice Bellard | case 2: |

478 | d7da8080 | Justin Ruggles | case 3: exp_strategy[blk] = EXP_D25; break; |

479 | default: exp_strategy[blk] = EXP_D15; break; |
||

480 | de6d9b64 | Fabrice Bellard | } |

481 | ce67b7cd | Justin Ruggles | blk = blk1; |

482 | de6d9b64 | Fabrice Bellard | } |

483 | } |
||

484 | |||

485 | 2f8ae522 | Justin Ruggles | |

486 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

487 | dfdf73eb | Justin Ruggles | ```
* Calculate exponent strategies for all channels.
``` |

488 | d7da8080 | Justin Ruggles | ```
* Array arrangement is reversed to simplify the per-channel calculation.
``` |

489 | dfdf73eb | Justin Ruggles | ```
*/
``` |

490 | 266d24be | Justin Ruggles | static void compute_exp_strategy(AC3EncodeContext *s) |

491 | dfdf73eb | Justin Ruggles | { |

492 | d7da8080 | Justin Ruggles | ```
int ch, blk;
``` |

493 | dfdf73eb | Justin Ruggles | |

494 | d7da8080 | Justin Ruggles | for (ch = 0; ch < s->fbw_channels; ch++) { |

495 | 5bff8590 | Justin Ruggles | ```
compute_exp_strategy_ch(s, s->exp_strategy[ch], s->blocks[0].exp[ch]);
``` |

496 | d7da8080 | Justin Ruggles | } |

497 | ```
if (s->lfe_on) {
``` |
||

498 | ch = s->lfe_channel; |
||

499 | 0429e4a6 | Justin Ruggles | ```
s->exp_strategy[ch][0] = EXP_D15;
``` |

500 | 06f6f785 | Justin Ruggles | for (blk = 1; blk < AC3_MAX_BLOCKS; blk++) |

501 | 0429e4a6 | Justin Ruggles | s->exp_strategy[ch][blk] = EXP_REUSE; |

502 | dfdf73eb | Justin Ruggles | } |

503 | } |
||

504 | |||

505 | |||

506 | ```
/**
``` |
||

507 | c36ce0f8 | Justin Ruggles | ```
* Update the exponents so that they are the ones the decoder will decode.
``` |

508 | ```
*/
``` |
||

509 | b5293036 | Justin Ruggles | static void encode_exponents_blk_ch(uint8_t *exp, int nb_exps, int exp_strategy) |

510 | de6d9b64 | Fabrice Bellard | { |

511 | e86ea34d | Justin Ruggles | ```
int nb_groups, i, k;
``` |

512 | de6d9b64 | Fabrice Bellard | |

513 | e86ea34d | Justin Ruggles | nb_groups = exponent_group_tab[exp_strategy-1][nb_exps] * 3; |

514 | de6d9b64 | Fabrice Bellard | |

515 | ```
/* for each group, compute the minimum exponent */
``` |
||

516 | 834550ea | Justin Ruggles | ```
switch(exp_strategy) {
``` |

517 | ```
case EXP_D25:
``` |
||

518 | for (i = 1, k = 1; i <= nb_groups; i++) { |
||

519 | uint8_t exp_min = exp[k]; |
||

520 | if (exp[k+1] < exp_min) |
||

521 | ```
exp_min = exp[k+1];
``` |
||

522 | exp[i] = exp_min; |
||

523 | ```
k += 2;
``` |
||

524 | de6d9b64 | Fabrice Bellard | } |

525 | 834550ea | Justin Ruggles | ```
break;
``` |

526 | ```
case EXP_D45:
``` |
||

527 | for (i = 1, k = 1; i <= nb_groups; i++) { |
||

528 | uint8_t exp_min = exp[k]; |
||

529 | if (exp[k+1] < exp_min) |
||

530 | ```
exp_min = exp[k+1];
``` |
||

531 | if (exp[k+2] < exp_min) |
||

532 | ```
exp_min = exp[k+2];
``` |
||

533 | if (exp[k+3] < exp_min) |
||

534 | ```
exp_min = exp[k+3];
``` |
||

535 | exp[i] = exp_min; |
||

536 | ```
k += 4;
``` |
||

537 | } |
||

538 | ```
break;
``` |
||

539 | 27af78cf | Justin Ruggles | } |

540 | de6d9b64 | Fabrice Bellard | |

541 | ```
/* constraint for DC exponent */
``` |
||

542 | 27af78cf | Justin Ruggles | if (exp[0] > 15) |

543 | exp[0] = 15; |
||

544 | de6d9b64 | Fabrice Bellard | |

545 | 6a988808 | Justin Ruggles | ```
/* decrease the delta between each groups to within 2 so that they can be
``` |

546 | ```
differentially encoded */
``` |
||

547 | for (i = 1; i <= nb_groups; i++) |
||

548 | 27af78cf | Justin Ruggles | exp[i] = FFMIN(exp[i], exp[i-1] + 2); |

549 | cdedf7e6 | Justin Ruggles | i--; |

550 | while (--i >= 0) |
||

551 | 27af78cf | Justin Ruggles | exp[i] = FFMIN(exp[i], exp[i+1] + 2); |

552 | e44cad52 | Jeff Muizelaar | |

553 | de6d9b64 | Fabrice Bellard | ```
/* now we have the exponent values the decoder will see */
``` |

554 | 834550ea | Justin Ruggles | ```
switch (exp_strategy) {
``` |

555 | ```
case EXP_D25:
``` |
||

556 | for (i = nb_groups, k = nb_groups * 2; i > 0; i--) { |
||

557 | uint8_t exp1 = exp[i]; |
||

558 | exp[k--] = exp1; |
||

559 | exp[k--] = exp1; |
||

560 | } |
||

561 | ```
break;
``` |
||

562 | ```
case EXP_D45:
``` |
||

563 | for (i = nb_groups, k = nb_groups * 4; i > 0; i--) { |
||

564 | exp[k] = exp[k-1] = exp[k-2] = exp[k-3] = exp[i]; |
||

565 | ```
k -= 4;
``` |
||

566 | } |
||

567 | ```
break;
``` |
||

568 | de6d9b64 | Fabrice Bellard | } |

569 | } |
||

570 | |||

571 | 2f8ae522 | Justin Ruggles | |

572 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

573 | dfdf73eb | Justin Ruggles | ```
* Encode exponents from original extracted form to what the decoder will see.
``` |

574 | ```
* This copies and groups exponents based on exponent strategy and reduces
``` |
||

575 | ```
* deltas between adjacent exponent groups so that they can be differentially
``` |
||

576 | ```
* encoded.
``` |
||

577 | ```
*/
``` |
||

578 | 266d24be | Justin Ruggles | static void encode_exponents(AC3EncodeContext *s) |

579 | dfdf73eb | Justin Ruggles | { |

580 | 7d87d56f | Justin Ruggles | ```
int blk, blk1, ch;
``` |

581 | uint8_t *exp, *exp1, *exp_strategy; |
||

582 | 964f2cf2 | Justin Ruggles | ```
int nb_coefs, num_reuse_blocks;
``` |

583 | dfdf73eb | Justin Ruggles | |

584 | for (ch = 0; ch < s->channels; ch++) { |
||

585 | 7d87d56f | Justin Ruggles | ```
exp = s->blocks[0].exp[ch];
``` |

586 | exp_strategy = s->exp_strategy[ch]; |
||

587 | nb_coefs = s->nb_coefs[ch]; |
||

588 | |||

589 | dfdf73eb | Justin Ruggles | ```
blk = 0;
``` |

590 | ```
while (blk < AC3_MAX_BLOCKS) {
``` |
||

591 | ```
blk1 = blk + 1;
``` |
||

592 | 964f2cf2 | Justin Ruggles | |

593 | ```
/* count the number of EXP_REUSE blocks after the current block */
``` |
||

594 | 0db5d2b0 | Justin Ruggles | ```
while (blk1 < AC3_MAX_BLOCKS && exp_strategy[blk1] == EXP_REUSE)
``` |

595 | dfdf73eb | Justin Ruggles | blk1++; |

596 | 964f2cf2 | Justin Ruggles | ```
num_reuse_blocks = blk1 - blk - 1;
``` |

597 | |||

598 | ```
/* for the EXP_REUSE case we select the min of the exponents */
``` |
||

599 | dda3f0ef | Justin Ruggles | s->ac3dsp.ac3_exponent_min(exp, num_reuse_blocks, nb_coefs); |

600 | 964f2cf2 | Justin Ruggles | |

601 | 0db5d2b0 | Justin Ruggles | encode_exponents_blk_ch(exp, nb_coefs, exp_strategy[blk]); |

602 | |||

603 | dfdf73eb | Justin Ruggles | ```
/* copy encoded exponents for reuse case */
``` |

604 | 7d87d56f | Justin Ruggles | exp1 = exp + AC3_MAX_COEFS; |

605 | while (blk < blk1-1) { |
||

606 | ```
memcpy(exp1, exp, nb_coefs * sizeof(*exp));
``` |
||

607 | exp1 += AC3_MAX_COEFS; |
||

608 | blk++; |
||

609 | dfdf73eb | Justin Ruggles | } |

610 | blk = blk1; |
||

611 | 7d87d56f | Justin Ruggles | exp = exp1; |

612 | dfdf73eb | Justin Ruggles | } |

613 | } |
||

614 | f94bacc5 | Justin Ruggles | } |

615 | |||

616 | |||

617 | ```
/**
``` |
||

618 | ```
* Group exponents.
``` |
||

619 | ```
* 3 delta-encoded exponents are in each 7-bit group. The number of groups
``` |
||

620 | ```
* varies depending on exponent strategy and bandwidth.
``` |
||

621 | ```
*/
``` |
||

622 | 266d24be | Justin Ruggles | static void group_exponents(AC3EncodeContext *s) |

623 | f94bacc5 | Justin Ruggles | { |

624 | ```
int blk, ch, i;
``` |
||

625 | e86ea34d | Justin Ruggles | ```
int group_size, nb_groups, bit_count;
``` |

626 | f94bacc5 | Justin Ruggles | uint8_t *p; |

627 | ```
int delta0, delta1, delta2;
``` |
||

628 | ```
int exp0, exp1;
``` |
||

629 | |||

630 | ```
bit_count = 0;
``` |
||

631 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

632 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

633 | f94bacc5 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

634 | 4b90c35d | Justin Ruggles | ```
int exp_strategy = s->exp_strategy[ch][blk];
``` |

635 | ```
if (exp_strategy == EXP_REUSE)
``` |
||

636 | f94bacc5 | Justin Ruggles | ```
continue;
``` |

637 | 4b90c35d | Justin Ruggles | group_size = exp_strategy + (exp_strategy == EXP_D45); |

638 | ```
nb_groups = exponent_group_tab[exp_strategy-1][s->nb_coefs[ch]];
``` |
||

639 | e86ea34d | Justin Ruggles | bit_count += 4 + (nb_groups * 7); |

640 | 27af78cf | Justin Ruggles | p = block->exp[ch]; |

641 | f94bacc5 | Justin Ruggles | |

642 | ```
/* DC exponent */
``` |
||

643 | exp1 = *p++; |
||

644 | 5901cebe | Justin Ruggles | ```
block->grouped_exp[ch][0] = exp1;
``` |

645 | f94bacc5 | Justin Ruggles | |

646 | ```
/* remaining exponents are delta encoded */
``` |
||

647 | e86ea34d | Justin Ruggles | for (i = 1; i <= nb_groups; i++) { |

648 | f94bacc5 | Justin Ruggles | ```
/* merge three delta in one code */
``` |

649 | exp0 = exp1; |
||

650 | ```
exp1 = p[0];
``` |
||

651 | p += group_size; |
||

652 | ```
delta0 = exp1 - exp0 + 2;
``` |
||

653 | 2d9a101a | Justin Ruggles | av_assert2(delta0 >= 0 && delta0 <= 4); |

654 | f94bacc5 | Justin Ruggles | |

655 | exp0 = exp1; |
||

656 | ```
exp1 = p[0];
``` |
||

657 | p += group_size; |
||

658 | ```
delta1 = exp1 - exp0 + 2;
``` |
||

659 | 2d9a101a | Justin Ruggles | av_assert2(delta1 >= 0 && delta1 <= 4); |

660 | f94bacc5 | Justin Ruggles | |

661 | exp0 = exp1; |
||

662 | ```
exp1 = p[0];
``` |
||

663 | p += group_size; |
||

664 | ```
delta2 = exp1 - exp0 + 2;
``` |
||

665 | 2d9a101a | Justin Ruggles | av_assert2(delta2 >= 0 && delta2 <= 4); |

666 | f94bacc5 | Justin Ruggles | |

667 | 5901cebe | Justin Ruggles | block->grouped_exp[ch][i] = ((delta0 * 5 + delta1) * 5) + delta2; |

668 | f94bacc5 | Justin Ruggles | } |

669 | } |
||

670 | } |
||

671 | dfdf73eb | Justin Ruggles | |

672 | 359c1d19 | Justin Ruggles | s->exponent_bits = bit_count; |

673 | dfdf73eb | Justin Ruggles | } |

674 | |||

675 | |||

676 | ```
/**
``` |
||

677 | ```
* Calculate final exponents from the supplied MDCT coefficients and exponent shift.
``` |
||

678 | ```
* Extract exponents from MDCT coefficients, calculate exponent strategies,
``` |
||

679 | ```
* and encode final exponents.
``` |
||

680 | ```
*/
``` |
||

681 | 266d24be | Justin Ruggles | static void process_exponents(AC3EncodeContext *s) |

682 | dfdf73eb | Justin Ruggles | { |

683 | 266d24be | Justin Ruggles | extract_exponents(s); |

684 | dfdf73eb | Justin Ruggles | |

685 | 266d24be | Justin Ruggles | compute_exp_strategy(s); |

686 | dfdf73eb | Justin Ruggles | |

687 | 266d24be | Justin Ruggles | encode_exponents(s); |

688 | f94bacc5 | Justin Ruggles | |

689 | 266d24be | Justin Ruggles | group_exponents(s); |

690 | dda3f0ef | Justin Ruggles | |

691 | emms_c(); |
||

692 | dfdf73eb | Justin Ruggles | } |

693 | |||

694 | |||

695 | ```
/**
``` |
||

696 | e7536ac5 | Justin Ruggles | ```
* Count frame bits that are based solely on fixed parameters.
``` |

697 | ```
* This only has to be run once when the encoder is initialized.
``` |
||

698 | ```
*/
``` |
||

699 | static void count_frame_bits_fixed(AC3EncodeContext *s) |
||

700 | { |
||

701 | static const int frame_bits_inc[8] = { 0, 0, 2, 2, 2, 4, 2, 4 }; |
||

702 | ```
int blk;
``` |
||

703 | ```
int frame_bits;
``` |
||

704 | |||

705 | ```
/* assumptions:
``` |
||

706 | ```
* no dynamic range codes
``` |
||

707 | ```
* no channel coupling
``` |
||

708 | ```
* bit allocation parameters do not change between blocks
``` |
||

709 | ```
* SNR offsets do not change between blocks
``` |
||

710 | ```
* no delta bit allocation
``` |
||

711 | ```
* no skipped data
``` |
||

712 | ```
* no auxilliary data
``` |
||

713 | ```
*/
``` |
||

714 | |||

715 | ```
/* header size */
``` |
||

716 | ```
frame_bits = 65;
``` |
||

717 | frame_bits += frame_bits_inc[s->channel_mode]; |
||

718 | |||

719 | ```
/* audio blocks */
``` |
||

720 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

721 | frame_bits += s->fbw_channels * 2 + 2; /* blksw * c, dithflag * c, dynrnge, cplstre */ |
||

722 | ```
if (s->channel_mode == AC3_CHMODE_STEREO) {
``` |
||

723 | ```
frame_bits++; /* rematstr */
``` |
||

724 | } |
||

725 | frame_bits += 2 * s->fbw_channels; /* chexpstr[2] * c */ |
||

726 | ```
if (s->lfe_on)
``` |
||

727 | ```
frame_bits++; /* lfeexpstr */
``` |
||

728 | ```
frame_bits++; /* baie */
``` |
||

729 | ```
frame_bits++; /* snr */
``` |
||

730 | frame_bits += 2; /* delta / skip */ |
||

731 | } |
||

732 | ```
frame_bits++; /* cplinu for block 0 */
``` |
||

733 | ```
/* bit alloc info */
``` |
||

734 | ```
/* sdcycod[2], fdcycod[2], sgaincod[2], dbpbcod[2], floorcod[3] */
``` |
||

735 | ```
/* csnroffset[6] */
``` |
||

736 | ```
/* (fsnoffset[4] + fgaincod[4]) * c */
``` |
||

737 | frame_bits += 2*4 + 3 + 6 + s->channels * (4 + 3); |
||

738 | |||

739 | ```
/* auxdatae, crcrsv */
``` |
||

740 | ```
frame_bits += 2;
``` |
||

741 | |||

742 | ```
/* CRC */
``` |
||

743 | ```
frame_bits += 16;
``` |
||

744 | |||

745 | s->frame_bits_fixed = frame_bits; |
||

746 | } |
||

747 | |||

748 | |||

749 | ```
/**
``` |
||

750 | 793bbf95 | Justin Ruggles | ```
* Initialize bit allocation.
``` |

751 | ```
* Set default parameter codes and calculate parameter values.
``` |
||

752 | ```
*/
``` |
||

753 | static void bit_alloc_init(AC3EncodeContext *s) |
||

754 | { |
||

755 | ```
int ch;
``` |
||

756 | |||

757 | ```
/* init default parameters */
``` |
||

758 | ```
s->slow_decay_code = 2;
``` |
||

759 | ```
s->fast_decay_code = 1;
``` |
||

760 | ```
s->slow_gain_code = 1;
``` |
||

761 | ec44dd5f | Justin Ruggles | ```
s->db_per_bit_code = 3;
``` |

762 | 50d71404 | Justin Ruggles | ```
s->floor_code = 7;
``` |

763 | 793bbf95 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) |

764 | ```
s->fast_gain_code[ch] = 4;
``` |
||

765 | |||

766 | ```
/* initial snr offset */
``` |
||

767 | ```
s->coarse_snr_offset = 40;
``` |
||

768 | |||

769 | ```
/* compute real values */
``` |
||

770 | ```
/* currently none of these values change during encoding, so we can just
``` |
||

771 | ```
set them once at initialization */
``` |
||

772 | s->bit_alloc.slow_decay = ff_ac3_slow_decay_tab[s->slow_decay_code] >> s->bit_alloc.sr_shift; |
||

773 | s->bit_alloc.fast_decay = ff_ac3_fast_decay_tab[s->fast_decay_code] >> s->bit_alloc.sr_shift; |
||

774 | s->bit_alloc.slow_gain = ff_ac3_slow_gain_tab[s->slow_gain_code]; |
||

775 | s->bit_alloc.db_per_bit = ff_ac3_db_per_bit_tab[s->db_per_bit_code]; |
||

776 | s->bit_alloc.floor = ff_ac3_floor_tab[s->floor_code]; |
||

777 | e7536ac5 | Justin Ruggles | |

778 | count_frame_bits_fixed(s); |
||

779 | 793bbf95 | Justin Ruggles | } |

780 | |||

781 | |||

782 | ```
/**
``` |
||

783 | 8999944e | Justin Ruggles | ```
* Count the bits used to encode the frame, minus exponents and mantissas.
``` |

784 | e7536ac5 | Justin Ruggles | ```
* Bits based on fixed parameters have already been counted, so now we just
``` |

785 | ```
* have to add the bits based on parameters that change during encoding.
``` |
||

786 | 8999944e | Justin Ruggles | ```
*/
``` |

787 | 266d24be | Justin Ruggles | static void count_frame_bits(AC3EncodeContext *s) |

788 | 8999944e | Justin Ruggles | { |

789 | ```
int blk, ch;
``` |
||

790 | e7536ac5 | Justin Ruggles | int frame_bits = 0; |

791 | 8999944e | Justin Ruggles | |

792 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

793 | dc7e07ac | Justin Ruggles | ```
/* stereo rematrixing */
``` |

794 | ```
if (s->channel_mode == AC3_CHMODE_STEREO &&
``` |
||

795 | s->blocks[blk].new_rematrixing_strategy) { |
||

796 | 53e35fd3 | Justin Ruggles | frame_bits += s->num_rematrixing_bands; |

797 | dc7e07ac | Justin Ruggles | } |

798 | |||

799 | 8999944e | Justin Ruggles | for (ch = 0; ch < s->fbw_channels; ch++) { |

800 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] != EXP_REUSE)
``` |

801 | 8999944e | Justin Ruggles | frame_bits += 6 + 2; /* chbwcod[6], gainrng[2] */ |

802 | } |
||

803 | } |
||

804 | e7536ac5 | Justin Ruggles | s->frame_bits = s->frame_bits_fixed + frame_bits; |

805 | 8999944e | Justin Ruggles | } |

806 | |||

807 | |||

808 | ```
/**
``` |
||

809 | c36ce0f8 | Justin Ruggles | ```
* Calculate the number of bits needed to encode a set of mantissas.
``` |

810 | ```
*/
``` |
||

811 | 126a29b8 | Justin Ruggles | static int compute_mantissa_size(int mant_cnt[5], uint8_t *bap, int nb_coefs) |

812 | de6d9b64 | Fabrice Bellard | { |

813 | 2d82d9b1 | Justin Ruggles | ```
int bits, b, i;
``` |

814 | de6d9b64 | Fabrice Bellard | |

815 | ```
bits = 0;
``` |
||

816 | 6a988808 | Justin Ruggles | for (i = 0; i < nb_coefs; i++) { |

817 | 2d82d9b1 | Justin Ruggles | b = bap[i]; |

818 | 126a29b8 | Justin Ruggles | if (b <= 4) { |

819 | ```
// bap=1 to bap=4 will be counted in compute_mantissa_size_final
``` |
||

820 | mant_cnt[b]++; |
||

821 | } else if (b <= 13) { |
||

822 | ```
// bap=5 to bap=13 use (bap-1) bits
``` |
||

823 | 2d82d9b1 | Justin Ruggles | ```
bits += b - 1;
``` |

824 | 126a29b8 | Justin Ruggles | ```
} else {
``` |

825 | ```
// bap=14 uses 14 bits and bap=15 uses 16 bits
``` |
||

826 | bits += (b == 14) ? 14 : 16; |
||

827 | de6d9b64 | Fabrice Bellard | } |

828 | } |
||

829 | ```
return bits;
``` |
||

830 | } |
||

831 | |||

832 | |||

833 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

834 | 126a29b8 | Justin Ruggles | ```
* Finalize the mantissa bit count by adding in the grouped mantissas.
``` |

835 | ```
*/
``` |
||

836 | static int compute_mantissa_size_final(int mant_cnt[5]) |
||

837 | { |
||

838 | ```
// bap=1 : 3 mantissas in 5 bits
``` |
||

839 | int bits = (mant_cnt[1] / 3) * 5; |
||

840 | ```
// bap=2 : 3 mantissas in 7 bits
``` |
||

841 | ```
// bap=4 : 2 mantissas in 7 bits
``` |
||

842 | bits += ((mant_cnt[2] / 3) + (mant_cnt[4] >> 1)) * 7; |
||

843 | ```
// bap=3 : each mantissa is 3 bits
``` |
||

844 | bits += mant_cnt[3] * 3; |
||

845 | ```
return bits;
``` |
||

846 | } |
||

847 | |||

848 | |||

849 | ```
/**
``` |
||

850 | c36ce0f8 | Justin Ruggles | ```
* Calculate masking curve based on the final exponents.
``` |

851 | ```
* Also calculate the power spectral densities to use in future calculations.
``` |
||

852 | ```
*/
``` |
||

853 | 266d24be | Justin Ruggles | static void bit_alloc_masking(AC3EncodeContext *s) |

854 | bbd16dea | Justin Ruggles | { |

855 | ```
int blk, ch;
``` |
||

856 | |||

857 | 6a988808 | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

858 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

859 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

860 | cf7c961b | Justin Ruggles | ```
/* We only need psd and mask for calculating bap.
``` |

861 | ```
Since we currently do not calculate bap when exponent
``` |
||

862 | ```
strategy is EXP_REUSE we do not need to calculate psd or mask. */
``` |
||

863 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] != EXP_REUSE) {
``` |

864 | 27af78cf | Justin Ruggles | ```
ff_ac3_bit_alloc_calc_psd(block->exp[ch], 0,
``` |

865 | bbd16dea | Justin Ruggles | s->nb_coefs[ch], |

866 | 5901cebe | Justin Ruggles | block->psd[ch], block->band_psd[ch]); |

867 | ff_ac3_bit_alloc_calc_mask(&s->bit_alloc, block->band_psd[ch], |
||

868 | bbd16dea | Justin Ruggles | ```
0, s->nb_coefs[ch],
``` |

869 | 5ce21342 | Justin Ruggles | ff_ac3_fast_gain_tab[s->fast_gain_code[ch]], |

870 | bbd16dea | Justin Ruggles | ch == s->lfe_channel, |

871 | cc2a8443 | Justin Ruggles | DBA_NONE, 0, NULL, NULL, NULL, |

872 | 5901cebe | Justin Ruggles | block->mask[ch]); |

873 | bbd16dea | Justin Ruggles | } |

874 | } |
||

875 | } |
||

876 | } |
||

877 | |||

878 | 2f8ae522 | Justin Ruggles | |

879 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

880 | 171bc51c | Justin Ruggles | ```
* Ensure that bap for each block and channel point to the current bap_buffer.
``` |

881 | ```
* They may have been switched during the bit allocation search.
``` |
||

882 | ```
*/
``` |
||

883 | static void reset_block_bap(AC3EncodeContext *s) |
||

884 | { |
||

885 | ```
int blk, ch;
``` |
||

886 | if (s->blocks[0].bap[0] == s->bap_buffer) |
||

887 | ```
return;
``` |
||

888 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

889 | for (ch = 0; ch < s->channels; ch++) { |
||

890 | s->blocks[blk].bap[ch] = &s->bap_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

891 | } |
||

892 | } |
||

893 | } |
||

894 | |||

895 | |||

896 | ```
/**
``` |
||

897 | c36ce0f8 | Justin Ruggles | ```
* Run the bit allocation with a given SNR offset.
``` |

898 | ```
* This calculates the bit allocation pointers that will be used to determine
``` |
||

899 | ```
* the quantization of each mantissa.
``` |
||

900 | 70fcd7ea | Justin Ruggles | ```
* @return the number of bits needed for mantissas if the given SNR offset is
``` |

901 | ```
* is used.
``` |
||

902 | c36ce0f8 | Justin Ruggles | ```
*/
``` |

903 | b5293036 | Justin Ruggles | static int bit_alloc(AC3EncodeContext *s, int snr_offset) |

904 | de6d9b64 | Fabrice Bellard | { |

905 | ce67b7cd | Justin Ruggles | ```
int blk, ch;
``` |

906 | a0d763fc | Justin Ruggles | ```
int mantissa_bits;
``` |

907 | 126a29b8 | Justin Ruggles | int mant_cnt[5]; |

908 | 319708da | Justin Ruggles | |

909 | a0d763fc | Justin Ruggles | snr_offset = (snr_offset - 240) << 2; |

910 | de6d9b64 | Fabrice Bellard | |

911 | 171bc51c | Justin Ruggles | reset_block_bap(s); |

912 | 70fcd7ea | Justin Ruggles | ```
mantissa_bits = 0;
``` |

913 | ce67b7cd | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

914 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

915 | 126a29b8 | Justin Ruggles | ```
// initialize grouped mantissa counts. these are set so that they are
``` |

916 | ```
// padded to the next whole group size when bits are counted in
``` |
||

917 | ```
// compute_mantissa_size_final
``` |
||

918 | mant_cnt[0] = mant_cnt[3] = 0; |
||

919 | mant_cnt[1] = mant_cnt[2] = 2; |
||

920 | mant_cnt[4] = 1; |
||

921 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

922 | 795063db | Justin Ruggles | ```
/* Currently the only bit allocation parameters which vary across
``` |

923 | ```
blocks within a frame are the exponent values. We can take
``` |
||

924 | ```
advantage of that by reusing the bit allocation pointers
``` |
||

925 | ```
whenever we reuse exponents. */
``` |
||

926 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] == EXP_REUSE) {
``` |

927 | 795063db | Justin Ruggles | ```
memcpy(block->bap[ch], s->blocks[blk-1].bap[ch], AC3_MAX_COEFS);
``` |

928 | ```
} else {
``` |
||

929 | 68e6b099 | Justin Ruggles | ```
ff_ac3_bit_alloc_calc_bap(block->mask[ch], block->psd[ch], 0,
``` |

930 | s->nb_coefs[ch], snr_offset, |
||

931 | s->bit_alloc.floor, ff_ac3_bap_tab, |
||

932 | block->bap[ch]); |
||

933 | 795063db | Justin Ruggles | } |

934 | 126a29b8 | Justin Ruggles | mantissa_bits += compute_mantissa_size(mant_cnt, block->bap[ch], s->nb_coefs[ch]); |

935 | de6d9b64 | Fabrice Bellard | } |

936 | 126a29b8 | Justin Ruggles | mantissa_bits += compute_mantissa_size_final(mant_cnt); |

937 | de6d9b64 | Fabrice Bellard | } |

938 | 70fcd7ea | Justin Ruggles | ```
return mantissa_bits;
``` |

939 | de6d9b64 | Fabrice Bellard | } |

940 | |||

941 | 2f8ae522 | Justin Ruggles | |

942 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

943 | cb6247cb | Justin Ruggles | ```
* Constant bitrate bit allocation search.
``` |

944 | ```
* Find the largest SNR offset that will allow data to fit in the frame.
``` |
||

945 | c36ce0f8 | Justin Ruggles | ```
*/
``` |

946 | cb6247cb | Justin Ruggles | static int cbr_bit_allocation(AC3EncodeContext *s) |

947 | de6d9b64 | Fabrice Bellard | { |

948 | 8999944e | Justin Ruggles | ```
int ch;
``` |

949 | 70fcd7ea | Justin Ruggles | ```
int bits_left;
``` |

950 | 98e34e71 | Justin Ruggles | ```
int snr_offset, snr_incr;
``` |

951 | de6d9b64 | Fabrice Bellard | |

952 | 70fcd7ea | Justin Ruggles | ```
bits_left = 8 * s->frame_size - (s->frame_bits + s->exponent_bits);
``` |

953 | 2d9a101a | Justin Ruggles | ```
av_assert2(bits_left >= 0);
``` |

954 | 7da4dc17 | Justin Ruggles | |

955 | a0d763fc | Justin Ruggles | ```
snr_offset = s->coarse_snr_offset << 4;
``` |

956 | 7da4dc17 | Justin Ruggles | |

957 | 9c84a72a | Justin Ruggles | ```
/* if previous frame SNR offset was 1023, check if current frame can also
``` |

958 | ```
use SNR offset of 1023. if so, skip the search. */
``` |
||

959 | if ((snr_offset | s->fine_snr_offset[0]) == 1023) { |
||

960 | if (bit_alloc(s, 1023) <= bits_left) |
||

961 | return 0; |
||

962 | } |
||

963 | |||

964 | a0d763fc | Justin Ruggles | while (snr_offset >= 0 && |

965 | 171bc51c | Justin Ruggles | bit_alloc(s, snr_offset) > bits_left) { |

966 | a0d763fc | Justin Ruggles | ```
snr_offset -= 64;
``` |

967 | 7da4dc17 | Justin Ruggles | } |

968 | 2d82d9b1 | Justin Ruggles | if (snr_offset < 0) |

969 | dc0bc0f8 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

970 | 7da4dc17 | Justin Ruggles | |

971 | 171bc51c | Justin Ruggles | FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); |

972 | 98e34e71 | Justin Ruggles | for (snr_incr = 64; snr_incr > 0; snr_incr >>= 2) { |

973 | 5128842e | Justin Ruggles | while (snr_offset + snr_incr <= 1023 && |

974 | 234b70d3 | Justin Ruggles | bit_alloc(s, snr_offset + snr_incr) <= bits_left) { |

975 | snr_offset += snr_incr; |
||

976 | FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); |
||

977 | } |
||

978 | de6d9b64 | Fabrice Bellard | } |

979 | 171bc51c | Justin Ruggles | FFSWAP(uint8_t *, s->bap_buffer, s->bap1_buffer); |

980 | reset_block_bap(s); |
||

981 | 115329f1 | Diego Biurrun | |

982 | a0d763fc | Justin Ruggles | ```
s->coarse_snr_offset = snr_offset >> 4;
``` |

983 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) |

984 | a0d763fc | Justin Ruggles | ```
s->fine_snr_offset[ch] = snr_offset & 0xF;
``` |

985 | 22c0b03c | Justin Ruggles | |

986 | de6d9b64 | Fabrice Bellard | return 0; |

987 | } |
||

988 | |||

989 | 2f8ae522 | Justin Ruggles | |

990 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

991 | 386268df | Justin Ruggles | ```
* Downgrade exponent strategies to reduce the bits used by the exponents.
``` |

992 | ```
* This is a fallback for when bit allocation fails with the normal exponent
``` |
||

993 | ```
* strategies. Each time this function is run it only downgrades the
``` |
||

994 | ```
* strategy in 1 channel of 1 block.
``` |
||

995 | ```
* @return non-zero if downgrade was unsuccessful
``` |
||

996 | ```
*/
``` |
||

997 | static int downgrade_exponents(AC3EncodeContext *s) |
||

998 | { |
||

999 | ```
int ch, blk;
``` |
||

1000 | |||

1001 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1002 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { |
||

1003 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] == EXP_D15) {
``` |

1004 | s->exp_strategy[ch][blk] = EXP_D25; |
||

1005 | 386268df | Justin Ruggles | return 0; |

1006 | } |
||

1007 | } |
||

1008 | } |
||

1009 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1010 | for (blk = AC3_MAX_BLOCKS-1; blk >= 0; blk--) { |
||

1011 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] == EXP_D25) {
``` |

1012 | s->exp_strategy[ch][blk] = EXP_D45; |
||

1013 | 386268df | Justin Ruggles | return 0; |

1014 | } |
||

1015 | } |
||

1016 | } |
||

1017 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1018 | ```
/* block 0 cannot reuse exponents, so only downgrade D45 to REUSE if
``` |
||

1019 | ```
the block number > 0 */
``` |
||

1020 | for (blk = AC3_MAX_BLOCKS-1; blk > 0; blk--) { |
||

1021 | 0429e4a6 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] > EXP_REUSE) {
``` |

1022 | s->exp_strategy[ch][blk] = EXP_REUSE; |
||

1023 | 386268df | Justin Ruggles | return 0; |

1024 | } |
||

1025 | } |
||

1026 | } |
||

1027 | return -1; |
||

1028 | } |
||

1029 | |||

1030 | |||

1031 | ```
/**
``` |
||

1032 | ```
* Reduce the bandwidth to reduce the number of bits used for a given SNR offset.
``` |
||

1033 | ```
* This is a second fallback for when bit allocation still fails after exponents
``` |
||

1034 | ```
* have been downgraded.
``` |
||

1035 | ```
* @return non-zero if bandwidth reduction was unsuccessful
``` |
||

1036 | ```
*/
``` |
||

1037 | static int reduce_bandwidth(AC3EncodeContext *s, int min_bw_code) |
||

1038 | { |
||

1039 | ```
int ch;
``` |
||

1040 | |||

1041 | if (s->bandwidth_code[0] > min_bw_code) { |
||

1042 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1043 | s->bandwidth_code[ch]--; |
||

1044 | s->nb_coefs[ch] = s->bandwidth_code[ch] * 3 + 73; |
||

1045 | } |
||

1046 | return 0; |
||

1047 | } |
||

1048 | return -1; |
||

1049 | } |
||

1050 | |||

1051 | |||

1052 | ```
/**
``` |
||

1053 | cb6247cb | Justin Ruggles | ```
* Perform bit allocation search.
``` |

1054 | ```
* Finds the SNR offset value that maximizes quality and fits in the specified
``` |
||

1055 | ```
* frame size. Output is the SNR offset and a set of bit allocation pointers
``` |
||

1056 | ```
* used to quantize the mantissas.
``` |
||

1057 | ```
*/
``` |
||

1058 | static int compute_bit_allocation(AC3EncodeContext *s) |
||

1059 | { |
||

1060 | 386268df | Justin Ruggles | ```
int ret;
``` |

1061 | |||

1062 | cb6247cb | Justin Ruggles | count_frame_bits(s); |

1063 | |||

1064 | bit_alloc_masking(s); |
||

1065 | |||

1066 | 386268df | Justin Ruggles | ret = cbr_bit_allocation(s); |

1067 | ```
while (ret) {
``` |
||

1068 | ```
/* fallback 1: downgrade exponents */
``` |
||

1069 | ```
if (!downgrade_exponents(s)) {
``` |
||

1070 | extract_exponents(s); |
||

1071 | encode_exponents(s); |
||

1072 | group_exponents(s); |
||

1073 | ret = compute_bit_allocation(s); |
||

1074 | ```
continue;
``` |
||

1075 | } |
||

1076 | |||

1077 | ```
/* fallback 2: reduce bandwidth */
``` |
||

1078 | ```
/* only do this if the user has not specified a specific cutoff
``` |
||

1079 | ```
frequency */
``` |
||

1080 | if (!s->cutoff && !reduce_bandwidth(s, 0)) { |
||

1081 | process_exponents(s); |
||

1082 | ret = compute_bit_allocation(s); |
||

1083 | ```
continue;
``` |
||

1084 | } |
||

1085 | |||

1086 | ```
/* fallbacks were not enough... */
``` |
||

1087 | ```
break;
``` |
||

1088 | } |
||

1089 | |||

1090 | ```
return ret;
``` |
||

1091 | cb6247cb | Justin Ruggles | } |

1092 | |||

1093 | |||

1094 | ```
/**
``` |
||

1095 | c36ce0f8 | Justin Ruggles | ```
* Symmetric quantization on 'levels' levels.
``` |

1096 | ```
*/
``` |
||

1097 | de6d9b64 | Fabrice Bellard | static inline int sym_quant(int c, int e, int levels) |

1098 | { |
||

1099 | 85ab2904 | Justin Ruggles | int v = ((((levels * c) >> (24 - e)) + 1) >> 1) + (levels >> 1); |

1100 | 7100d63c | Justin Ruggles | ```
av_assert2(v >= 0 && v < levels);
``` |

1101 | de6d9b64 | Fabrice Bellard | ```
return v;
``` |

1102 | } |
||

1103 | |||

1104 | 2f8ae522 | Justin Ruggles | |

1105 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1106 | ```
* Asymmetric quantization on 2^qbits levels.
``` |
||

1107 | ```
*/
``` |
||

1108 | de6d9b64 | Fabrice Bellard | static inline int asym_quant(int c, int e, int qbits) |

1109 | { |
||

1110 | ```
int lshift, m, v;
``` |
||

1111 | |||

1112 | ```
lshift = e + qbits - 24;
``` |
||

1113 | if (lshift >= 0) |
||

1114 | v = c << lshift; |
||

1115 | ```
else
``` |
||

1116 | v = c >> (-lshift); |
||

1117 | ```
/* rounding */
``` |
||

1118 | v = (v + 1) >> 1; |
||

1119 | m = (1 << (qbits-1)); |
||

1120 | ```
if (v >= m)
``` |
||

1121 | ```
v = m - 1;
``` |
||

1122 | 7100d63c | Justin Ruggles | av_assert2(v >= -m); |

1123 | de6d9b64 | Fabrice Bellard | return v & ((1 << qbits)-1); |

1124 | } |
||

1125 | |||

1126 | 2f8ae522 | Justin Ruggles | |

1127 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1128 | b6a1e523 | Justin Ruggles | ```
* Quantize a set of mantissas for a single channel in a single block.
``` |

1129 | ```
*/
``` |
||

1130 | ac05f903 | Justin Ruggles | static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef, |

1131 | 323e6fea | Justin | uint8_t *exp, |

1132 | b5293036 | Justin Ruggles | ```
uint8_t *bap, uint16_t *qmant, int n)
``` |

1133 | b6a1e523 | Justin Ruggles | { |

1134 | ```
int i;
``` |
||

1135 | |||

1136 | for (i = 0; i < n; i++) { |
||

1137 | ```
int v;
``` |
||

1138 | ac05f903 | Justin Ruggles | ```
int c = fixed_coef[i];
``` |

1139 | 323e6fea | Justin | ```
int e = exp[i];
``` |

1140 | b6a1e523 | Justin Ruggles | ```
int b = bap[i];
``` |

1141 | ```
switch (b) {
``` |
||

1142 | case 0: |
||

1143 | ```
v = 0;
``` |
||

1144 | ```
break;
``` |
||

1145 | case 1: |
||

1146 | ```
v = sym_quant(c, e, 3);
``` |
||

1147 | ```
switch (s->mant1_cnt) {
``` |
||

1148 | case 0: |
||

1149 | s->qmant1_ptr = &qmant[i]; |
||

1150 | ```
v = 9 * v;
``` |
||

1151 | ```
s->mant1_cnt = 1;
``` |
||

1152 | ```
break;
``` |
||

1153 | case 1: |
||

1154 | ```
*s->qmant1_ptr += 3 * v;
``` |
||

1155 | ```
s->mant1_cnt = 2;
``` |
||

1156 | ```
v = 128;
``` |
||

1157 | ```
break;
``` |
||

1158 | ```
default:
``` |
||

1159 | *s->qmant1_ptr += v; |
||

1160 | ```
s->mant1_cnt = 0;
``` |
||

1161 | ```
v = 128;
``` |
||

1162 | ```
break;
``` |
||

1163 | } |
||

1164 | ```
break;
``` |
||

1165 | case 2: |
||

1166 | ```
v = sym_quant(c, e, 5);
``` |
||

1167 | ```
switch (s->mant2_cnt) {
``` |
||

1168 | case 0: |
||

1169 | s->qmant2_ptr = &qmant[i]; |
||

1170 | ```
v = 25 * v;
``` |
||

1171 | ```
s->mant2_cnt = 1;
``` |
||

1172 | ```
break;
``` |
||

1173 | case 1: |
||

1174 | ```
*s->qmant2_ptr += 5 * v;
``` |
||

1175 | ```
s->mant2_cnt = 2;
``` |
||

1176 | ```
v = 128;
``` |
||

1177 | ```
break;
``` |
||

1178 | ```
default:
``` |
||

1179 | *s->qmant2_ptr += v; |
||

1180 | ```
s->mant2_cnt = 0;
``` |
||

1181 | ```
v = 128;
``` |
||

1182 | ```
break;
``` |
||

1183 | } |
||

1184 | ```
break;
``` |
||

1185 | case 3: |
||

1186 | ```
v = sym_quant(c, e, 7);
``` |
||

1187 | ```
break;
``` |
||

1188 | case 4: |
||

1189 | ```
v = sym_quant(c, e, 11);
``` |
||

1190 | ```
switch (s->mant4_cnt) {
``` |
||

1191 | case 0: |
||

1192 | s->qmant4_ptr = &qmant[i]; |
||

1193 | ```
v = 11 * v;
``` |
||

1194 | ```
s->mant4_cnt = 1;
``` |
||

1195 | ```
break;
``` |
||

1196 | ```
default:
``` |
||

1197 | *s->qmant4_ptr += v; |
||

1198 | ```
s->mant4_cnt = 0;
``` |
||

1199 | ```
v = 128;
``` |
||

1200 | ```
break;
``` |
||

1201 | } |
||

1202 | ```
break;
``` |
||

1203 | case 5: |
||

1204 | ```
v = sym_quant(c, e, 15);
``` |
||

1205 | ```
break;
``` |
||

1206 | case 14: |
||

1207 | ```
v = asym_quant(c, e, 14);
``` |
||

1208 | ```
break;
``` |
||

1209 | case 15: |
||

1210 | ```
v = asym_quant(c, e, 16);
``` |
||

1211 | ```
break;
``` |
||

1212 | ```
default:
``` |
||

1213 | ```
v = asym_quant(c, e, b - 1);
``` |
||

1214 | ```
break;
``` |
||

1215 | } |
||

1216 | qmant[i] = v; |
||

1217 | } |
||

1218 | } |
||

1219 | |||

1220 | |||

1221 | ```
/**
``` |
||

1222 | ```
* Quantize mantissas using coefficients, exponents, and bit allocation pointers.
``` |
||

1223 | ```
*/
``` |
||

1224 | 266d24be | Justin Ruggles | static void quantize_mantissas(AC3EncodeContext *s) |

1225 | b6a1e523 | Justin Ruggles | { |

1226 | ```
int blk, ch;
``` |
||

1227 | |||

1228 | |||

1229 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

1230 | 5901cebe | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

1231 | b6a1e523 | Justin Ruggles | ```
s->mant1_cnt = s->mant2_cnt = s->mant4_cnt = 0;
``` |

1232 | ```
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
``` |
||

1233 | |||

1234 | for (ch = 0; ch < s->channels; ch++) { |
||

1235 | 323e6fea | Justin | quantize_mantissas_blk_ch(s, block->fixed_coef[ch], |

1236 | 27af78cf | Justin Ruggles | block->exp[ch], block->bap[ch], |

1237 | 5901cebe | Justin Ruggles | block->qmant[ch], s->nb_coefs[ch]); |

1238 | b6a1e523 | Justin Ruggles | } |

1239 | } |
||

1240 | } |
||

1241 | |||

1242 | |||

1243 | ```
/**
``` |
||

1244 | 5b44ede0 | Justin Ruggles | ```
* Write the AC-3 frame header to the output bitstream.
``` |

1245 | ```
*/
``` |
||

1246 | static void output_frame_header(AC3EncodeContext *s) |
||

1247 | { |
||

1248 | put_bits(&s->pb, 16, 0x0b77); /* frame header */ |
||

1249 | put_bits(&s->pb, 16, 0); /* crc1: will be filled later */ |
||

1250 | ```
put_bits(&s->pb, 2, s->bit_alloc.sr_code);
``` |
||

1251 | put_bits(&s->pb, 6, s->frame_size_code + (s->frame_size - s->frame_size_min) / 2); |
||

1252 | ```
put_bits(&s->pb, 5, s->bitstream_id);
``` |
||

1253 | ```
put_bits(&s->pb, 3, s->bitstream_mode);
``` |
||

1254 | ```
put_bits(&s->pb, 3, s->channel_mode);
``` |
||

1255 | if ((s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO) |
||

1256 | put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ |
||

1257 | if (s->channel_mode & 0x04) |
||

1258 | put_bits(&s->pb, 2, 1); /* XXX -6 dB */ |
||

1259 | ```
if (s->channel_mode == AC3_CHMODE_STEREO)
``` |
||

1260 | put_bits(&s->pb, 2, 0); /* surround not indicated */ |
||

1261 | put_bits(&s->pb, 1, s->lfe_on); /* LFE */ |
||

1262 | put_bits(&s->pb, 5, 31); /* dialog norm: -31 db */ |
||

1263 | put_bits(&s->pb, 1, 0); /* no compression control word */ |
||

1264 | put_bits(&s->pb, 1, 0); /* no lang code */ |
||

1265 | put_bits(&s->pb, 1, 0); /* no audio production info */ |
||

1266 | put_bits(&s->pb, 1, 0); /* no copyright */ |
||

1267 | put_bits(&s->pb, 1, 1); /* original bitstream */ |
||

1268 | put_bits(&s->pb, 1, 0); /* no time code 1 */ |
||

1269 | put_bits(&s->pb, 1, 0); /* no time code 2 */ |
||

1270 | put_bits(&s->pb, 1, 0); /* no additional bit stream info */ |
||

1271 | } |
||

1272 | |||

1273 | |||

1274 | ```
/**
``` |
||

1275 | c36ce0f8 | Justin Ruggles | ```
* Write one audio block to the output bitstream.
``` |

1276 | ```
*/
``` |
||

1277 | 5fc2e007 | Justin Ruggles | static void output_audio_block(AC3EncodeContext *s, int blk) |

1278 | de6d9b64 | Fabrice Bellard | { |

1279 | f94bacc5 | Justin Ruggles | ```
int ch, i, baie, rbnd;
``` |

1280 | 5fc2e007 | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

1281 | de6d9b64 | Fabrice Bellard | |

1282 | 2d82d9b1 | Justin Ruggles | ```
/* block switching */
``` |

1283 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->fbw_channels; ch++) |

1284 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 1, 0); |

1285 | |||

1286 | ```
/* dither flags */
``` |
||

1287 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->fbw_channels; ch++) |

1288 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 1, 1); |

1289 | |||

1290 | ```
/* dynamic range codes */
``` |
||

1291 | put_bits(&s->pb, 1, 0); |
||

1292 | |||

1293 | ```
/* channel coupling */
``` |
||

1294 | 5fc2e007 | Justin Ruggles | ```
if (!blk) {
``` |

1295 | de6d9b64 | Fabrice Bellard | put_bits(&s->pb, 1, 1); /* coupling strategy present */ |

1296 | put_bits(&s->pb, 1, 0); /* no coupling strategy */ |
||

1297 | ```
} else {
``` |
||

1298 | put_bits(&s->pb, 1, 0); /* no new coupling strategy */ |
||

1299 | } |
||

1300 | |||

1301 | 2d82d9b1 | Justin Ruggles | ```
/* stereo rematrixing */
``` |

1302 | 6a988808 | Justin Ruggles | ```
if (s->channel_mode == AC3_CHMODE_STEREO) {
``` |

1303 | dc7e07ac | Justin Ruggles | ```
put_bits(&s->pb, 1, block->new_rematrixing_strategy);
``` |

1304 | ```
if (block->new_rematrixing_strategy) {
``` |
||

1305 | ```
/* rematrixing flags */
``` |
||

1306 | 53e35fd3 | Justin Ruggles | for (rbnd = 0; rbnd < s->num_rematrixing_bands; rbnd++) |

1307 | dc7e07ac | Justin Ruggles | ```
put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]);
``` |

1308 | 6a988808 | Justin Ruggles | } |

1309 | } |
||

1310 | de6d9b64 | Fabrice Bellard | |

1311 | ```
/* exponent strategy */
``` |
||

1312 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->fbw_channels; ch++) |

1313 | 5fc2e007 | Justin Ruggles | ```
put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
``` |

1314 | 6a988808 | Justin Ruggles | ```
if (s->lfe_on)
``` |

1315 | 5fc2e007 | Justin Ruggles | ```
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
``` |

1316 | 30b68f33 | Zdenek Kabelac | |

1317 | 6a988808 | Justin Ruggles | ```
/* bandwidth */
``` |

1318 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1319 | 5fc2e007 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] != EXP_REUSE)
``` |

1320 | 2d2692eb | Justin Ruggles | ```
put_bits(&s->pb, 6, s->bandwidth_code[ch]);
``` |

1321 | de6d9b64 | Fabrice Bellard | } |

1322 | 115329f1 | Diego Biurrun | |

1323 | de6d9b64 | Fabrice Bellard | ```
/* exponents */
``` |

1324 | 2d2692eb | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

1325 | e86ea34d | Justin Ruggles | ```
int nb_groups;
``` |

1326 | |||

1327 | 5fc2e007 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] == EXP_REUSE)
``` |

1328 | de6d9b64 | Fabrice Bellard | ```
continue;
``` |

1329 | |||

1330 | 2d82d9b1 | Justin Ruggles | ```
/* DC exponent */
``` |

1331 | 5901cebe | Justin Ruggles | put_bits(&s->pb, 4, block->grouped_exp[ch][0]); |

1332 | f94bacc5 | Justin Ruggles | |

1333 | 2d82d9b1 | Justin Ruggles | ```
/* exponent groups */
``` |

1334 | 5fc2e007 | Justin Ruggles | ```
nb_groups = exponent_group_tab[s->exp_strategy[ch][blk]-1][s->nb_coefs[ch]];
``` |

1335 | e86ea34d | Justin Ruggles | for (i = 1; i <= nb_groups; i++) |

1336 | 5901cebe | Justin Ruggles | ```
put_bits(&s->pb, 7, block->grouped_exp[ch][i]);
``` |

1337 | de6d9b64 | Fabrice Bellard | |

1338 | 2d82d9b1 | Justin Ruggles | ```
/* gain range info */
``` |

1339 | bb270c08 | Diego Biurrun | ```
if (ch != s->lfe_channel)
``` |

1340 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 2, 0); |

1341 | de6d9b64 | Fabrice Bellard | } |

1342 | |||

1343 | ```
/* bit allocation info */
``` |
||

1344 | 5fc2e007 | Justin Ruggles | ```
baie = (blk == 0);
``` |

1345 | de6d9b64 | Fabrice Bellard | ```
put_bits(&s->pb, 1, baie);
``` |

1346 | ```
if (baie) {
``` |
||

1347 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 2, s->slow_decay_code);
``` |

1348 | ```
put_bits(&s->pb, 2, s->fast_decay_code);
``` |
||

1349 | ```
put_bits(&s->pb, 2, s->slow_gain_code);
``` |
||

1350 | ```
put_bits(&s->pb, 2, s->db_per_bit_code);
``` |
||

1351 | ```
put_bits(&s->pb, 3, s->floor_code);
``` |
||

1352 | de6d9b64 | Fabrice Bellard | } |

1353 | |||

1354 | ```
/* snr offset */
``` |
||

1355 | 6a988808 | Justin Ruggles | ```
put_bits(&s->pb, 1, baie);
``` |

1356 | de6d9b64 | Fabrice Bellard | ```
if (baie) {
``` |

1357 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 6, s->coarse_snr_offset);
``` |

1358 | 6a988808 | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

1359 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 4, s->fine_snr_offset[ch]);
``` |

1360 | ```
put_bits(&s->pb, 3, s->fast_gain_code[ch]);
``` |
||

1361 | de6d9b64 | Fabrice Bellard | } |

1362 | } |
||

1363 | 115329f1 | Diego Biurrun | |

1364 | de6d9b64 | Fabrice Bellard | put_bits(&s->pb, 1, 0); /* no delta bit allocation */ |

1365 | put_bits(&s->pb, 1, 0); /* no data to skip */ |
||

1366 | |||

1367 | 2d82d9b1 | Justin Ruggles | ```
/* mantissas */
``` |

1368 | 2d2692eb | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

1369 | de6d9b64 | Fabrice Bellard | ```
int b, q;
``` |

1370 | 6a988808 | Justin Ruggles | for (i = 0; i < s->nb_coefs[ch]; i++) { |

1371 | 5901cebe | Justin Ruggles | q = block->qmant[ch][i]; |

1372 | 171bc51c | Justin Ruggles | b = block->bap[ch][i]; |

1373 | 6a988808 | Justin Ruggles | ```
switch (b) {
``` |

1374 | case 0: break; |
||

1375 | case 1: if (q != 128) put_bits(&s->pb, 5, q); break; |
||

1376 | case 2: if (q != 128) put_bits(&s->pb, 7, q); break; |
||

1377 | case 3: put_bits(&s->pb, 3, q); break; |
||

1378 | case 4: if (q != 128) put_bits(&s->pb, 7, q); break; |
||

1379 | case 14: put_bits(&s->pb, 14, q); break; |
||

1380 | case 15: put_bits(&s->pb, 16, q); break; |
||

1381 | default: put_bits(&s->pb, b-1, q); break; |
||

1382 | de6d9b64 | Fabrice Bellard | } |

1383 | } |
||

1384 | } |
||

1385 | } |
||

1386 | |||

1387 | 2f8ae522 | Justin Ruggles | |

1388 | c36ce0f8 | Justin Ruggles | ```
/** CRC-16 Polynomial */
``` |

1389 | de6d9b64 | Fabrice Bellard | #define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)) |

1390 | |||

1391 | 2f8ae522 | Justin Ruggles | |

1392 | de6d9b64 | Fabrice Bellard | static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) |

1393 | { |
||

1394 | unsigned int c; |
||

1395 | |||

1396 | ```
c = 0;
``` |
||

1397 | ```
while (a) {
``` |
||

1398 | if (a & 1) |
||

1399 | c ^= b; |
||

1400 | ```
a = a >> 1;
``` |
||

1401 | ```
b = b << 1;
``` |
||

1402 | if (b & (1 << 16)) |
||

1403 | b ^= poly; |
||

1404 | } |
||

1405 | ```
return c;
``` |
||

1406 | } |
||

1407 | |||

1408 | 2f8ae522 | Justin Ruggles | |

1409 | de6d9b64 | Fabrice Bellard | static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) |

1410 | { |
||

1411 | unsigned int r; |
||

1412 | ```
r = 1;
``` |
||

1413 | ```
while (n) {
``` |
||

1414 | if (n & 1) |
||

1415 | r = mul_poly(r, a, poly); |
||

1416 | a = mul_poly(a, a, poly); |
||

1417 | ```
n >>= 1;
``` |
||

1418 | } |
||

1419 | ```
return r;
``` |
||

1420 | } |
||

1421 | |||

1422 | 2f8ae522 | Justin Ruggles | |

1423 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1424 | ```
* Fill the end of the frame with 0's and compute the two CRCs.
``` |
||

1425 | ```
*/
``` |
||

1426 | 1971ab6e | Justin Ruggles | static void output_frame_end(AC3EncodeContext *s) |

1427 | de6d9b64 | Fabrice Bellard | { |

1428 | a897423b | Justin Ruggles | ```
const AVCRC *crc_ctx = av_crc_get_table(AV_CRC_16_ANSI);
``` |

1429 | e96dc767 | Justin Ruggles | ```
int frame_size_58, pad_bytes, crc1, crc2_partial, crc2, crc_inv;
``` |

1430 | 0c1a9eda | Zdenek Kabelac | uint8_t *frame; |

1431 | de6d9b64 | Fabrice Bellard | |

1432 | 0e9b0643 | Justin Ruggles | frame_size_58 = ((s->frame_size >> 2) + (s->frame_size >> 4)) << 1; |

1433 | 2d82d9b1 | Justin Ruggles | |

1434 | ```
/* pad the remainder of the frame with zeros */
``` |
||

1435 | 2d9a101a | Justin Ruggles | av_assert2(s->frame_size * 8 - put_bits_count(&s->pb) >= 18); |

1436 | de6d9b64 | Fabrice Bellard | flush_put_bits(&s->pb); |

1437 | frame = s->pb.buf; |
||

1438 | 427e2293 | Justin Ruggles | ```
pad_bytes = s->frame_size - (put_bits_ptr(&s->pb) - frame) - 2;
``` |

1439 | 7100d63c | Justin Ruggles | ```
av_assert2(pad_bytes >= 0);
``` |

1440 | eed00252 | Justin Ruggles | if (pad_bytes > 0) |

1441 | ```
memset(put_bits_ptr(&s->pb), 0, pad_bytes);
``` |
||

1442 | 115329f1 | Diego Biurrun | |

1443 | 2d82d9b1 | Justin Ruggles | ```
/* compute crc1 */
``` |

1444 | ```
/* this is not so easy because it is at the beginning of the data... */
``` |
||

1445 | b51c740e | Justin Ruggles | crc1 = av_bswap16(av_crc(crc_ctx, 0, frame + 4, frame_size_58 - 4)); |

1446 | a81d7c6a | Justin Ruggles | crc_inv = s->crc_inv[s->frame_size > s->frame_size_min]; |

1447 | 6a988808 | Justin Ruggles | crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); |

1448 | ```
AV_WB16(frame + 2, crc1);
``` |
||

1449 | 115329f1 | Diego Biurrun | |

1450 | 2d82d9b1 | Justin Ruggles | ```
/* compute crc2 */
``` |

1451 | e96dc767 | Justin Ruggles | ```
crc2_partial = av_crc(crc_ctx, 0, frame + frame_size_58,
``` |

1452 | ```
s->frame_size - frame_size_58 - 3);
``` |
||

1453 | crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); |
||

1454 | ```
/* ensure crc2 does not match sync word by flipping crcrsv bit if needed */
``` |
||

1455 | if (crc2 == 0x770B) { |
||

1456 | frame[s->frame_size - 3] ^= 0x1; |
||

1457 | crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); |
||

1458 | } |
||

1459 | crc2 = av_bswap16(crc2); |
||

1460 | 0e9b0643 | Justin Ruggles | ```
AV_WB16(frame + s->frame_size - 2, crc2);
``` |

1461 | de6d9b64 | Fabrice Bellard | } |

1462 | |||

1463 | 2f8ae522 | Justin Ruggles | |

1464 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1465 | 67d979fe | Justin Ruggles | ```
* Write the frame to the output bitstream.
``` |

1466 | ```
*/
``` |
||

1467 | b5293036 | Justin Ruggles | static void output_frame(AC3EncodeContext *s, unsigned char *frame) |

1468 | 67d979fe | Justin Ruggles | { |

1469 | ```
int blk;
``` |
||

1470 | |||

1471 | init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); |
||

1472 | |||

1473 | output_frame_header(s); |
||

1474 | |||

1475 | 2d82d9b1 | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) |

1476 | 266d24be | Justin Ruggles | output_audio_block(s, blk); |

1477 | 67d979fe | Justin Ruggles | |

1478 | output_frame_end(s); |
||

1479 | } |
||

1480 | |||

1481 | |||

1482 | ```
/**
``` |
||

1483 | c36ce0f8 | Justin Ruggles | ```
* Encode a single AC-3 frame.
``` |

1484 | ```
*/
``` |
||

1485 | b5293036 | Justin Ruggles | static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, |

1486 | int buf_size, void *data) |
||

1487 | de6d9b64 | Fabrice Bellard | { |

1488 | AC3EncodeContext *s = avctx->priv_data; |
||

1489 | 0cbd5ff7 | Justin Ruggles | ```
const SampleType *samples = data;
``` |

1490 | dc0bc0f8 | Justin Ruggles | ```
int ret;
``` |

1491 | de6d9b64 | Fabrice Bellard | |

1492 | 160d85f5 | Justin Ruggles | if (s->bit_alloc.sr_code == 1) |

1493 | adjust_frame_size(s); |
||

1494 | |||

1495 | 266d24be | Justin Ruggles | deinterleave_input_samples(s, samples); |

1496 | 12ed6226 | Justin Ruggles | |

1497 | 266d24be | Justin Ruggles | apply_mdct(s); |

1498 | 115329f1 | Diego Biurrun | |

1499 | ac05f903 | Justin Ruggles | scale_coefficients(s); |

1500 | |||

1501 | 323e6fea | Justin | compute_rematrixing_strategy(s); |

1502 | |||

1503 | dc7e07ac | Justin Ruggles | apply_rematrixing(s); |

1504 | |||

1505 | 266d24be | Justin Ruggles | process_exponents(s); |

1506 | de6d9b64 | Fabrice Bellard | |

1507 | 266d24be | Justin Ruggles | ret = compute_bit_allocation(s); |

1508 | dc0bc0f8 | Justin Ruggles | ```
if (ret) {
``` |

1509 | ```
av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n");
``` |
||

1510 | ```
return ret;
``` |
||

1511 | } |
||

1512 | 084f5c5a | Justin Ruggles | |

1513 | 266d24be | Justin Ruggles | quantize_mantissas(s); |

1514 | b6a1e523 | Justin Ruggles | |

1515 | 266d24be | Justin Ruggles | output_frame(s, frame); |

1516 | 1971ab6e | Justin Ruggles | |

1517 | 427e2293 | Justin Ruggles | ```
return s->frame_size;
``` |

1518 | de6d9b64 | Fabrice Bellard | } |

1519 | |||

1520 | 2f8ae522 | Justin Ruggles | |

1521 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1522 | ```
* Finalize encoding and free any memory allocated by the encoder.
``` |
||

1523 | ```
*/
``` |
||

1524 | a0a9204e | Justin Ruggles | static av_cold int ac3_encode_close(AVCodecContext *avctx) |

1525 | 492cd3a9 | Michael Niedermayer | { |

1526 | e8d21fba | Justin Ruggles | ```
int blk, ch;
``` |

1527 | 171bc51c | Justin Ruggles | AC3EncodeContext *s = avctx->priv_data; |

1528 | |||

1529 | e8d21fba | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) |

1530 | av_freep(&s->planar_samples[ch]); |
||

1531 | av_freep(&s->planar_samples); |
||

1532 | 171bc51c | Justin Ruggles | av_freep(&s->bap_buffer); |

1533 | av_freep(&s->bap1_buffer); |
||

1534 | b6f6204d | Justin Ruggles | av_freep(&s->mdct_coef_buffer); |

1535 | ac05f903 | Justin Ruggles | av_freep(&s->fixed_coef_buffer); |

1536 | b6f6204d | Justin Ruggles | av_freep(&s->exp_buffer); |

1537 | av_freep(&s->grouped_exp_buffer); |
||

1538 | av_freep(&s->psd_buffer); |
||

1539 | av_freep(&s->band_psd_buffer); |
||

1540 | av_freep(&s->mask_buffer); |
||

1541 | av_freep(&s->qmant_buffer); |
||

1542 | 171bc51c | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

1543 | AC3Block *block = &s->blocks[blk]; |
||

1544 | av_freep(&block->bap); |
||

1545 | b6f6204d | Justin Ruggles | av_freep(&block->mdct_coef); |

1546 | ac05f903 | Justin Ruggles | av_freep(&block->fixed_coef); |

1547 | b6f6204d | Justin Ruggles | av_freep(&block->exp); |

1548 | av_freep(&block->grouped_exp); |
||

1549 | av_freep(&block->psd); |
||

1550 | av_freep(&block->band_psd); |
||

1551 | av_freep(&block->mask); |
||

1552 | av_freep(&block->qmant); |
||

1553 | 171bc51c | Justin Ruggles | } |

1554 | |||

1555 | c41ac4f8 | Justin Ruggles | mdct_end(&s->mdct); |

1556 | |||

1557 | 492cd3a9 | Michael Niedermayer | av_freep(&avctx->coded_frame); |

1558 | ef9f7306 | MÃ¥ns RullgÃ¥rd | return 0; |

1559 | 492cd3a9 | Michael Niedermayer | } |

1560 | |||

1561 | 2f8ae522 | Justin Ruggles | |

1562 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1563 | ```
* Set channel information during initialization.
``` |
||

1564 | ```
*/
``` |
||

1565 | e77fd066 | Justin Ruggles | static av_cold int set_channel_info(AC3EncodeContext *s, int channels, |

1566 | int64_t *channel_layout) |
||

1567 | { |
||

1568 | ```
int ch_layout;
``` |
||

1569 | |||

1570 | if (channels < 1 || channels > AC3_MAX_CHANNELS) |
||

1571 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1572 | e77fd066 | Justin Ruggles | if ((uint64_t)*channel_layout > 0x7FF) |

1573 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1574 | e77fd066 | Justin Ruggles | ch_layout = *channel_layout; |

1575 | ```
if (!ch_layout)
``` |
||

1576 | ```
ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL);
``` |
||

1577 | ```
if (av_get_channel_layout_nb_channels(ch_layout) != channels)
``` |
||

1578 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1579 | e77fd066 | Justin Ruggles | |

1580 | s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); |
||

1581 | s->channels = channels; |
||

1582 | s->fbw_channels = channels - s->lfe_on; |
||

1583 | ```
s->lfe_channel = s->lfe_on ? s->fbw_channels : -1;
``` |
||

1584 | ```
if (s->lfe_on)
``` |
||

1585 | ch_layout -= AV_CH_LOW_FREQUENCY; |
||

1586 | |||

1587 | ```
switch (ch_layout) {
``` |
||

1588 | case AV_CH_LAYOUT_MONO: s->channel_mode = AC3_CHMODE_MONO; break; |
||

1589 | case AV_CH_LAYOUT_STEREO: s->channel_mode = AC3_CHMODE_STEREO; break; |
||

1590 | case AV_CH_LAYOUT_SURROUND: s->channel_mode = AC3_CHMODE_3F; break; |
||

1591 | case AV_CH_LAYOUT_2_1: s->channel_mode = AC3_CHMODE_2F1R; break; |
||

1592 | case AV_CH_LAYOUT_4POINT0: s->channel_mode = AC3_CHMODE_3F1R; break; |
||

1593 | ```
case AV_CH_LAYOUT_QUAD:
``` |
||

1594 | case AV_CH_LAYOUT_2_2: s->channel_mode = AC3_CHMODE_2F2R; break; |
||

1595 | ```
case AV_CH_LAYOUT_5POINT0:
``` |
||

1596 | case AV_CH_LAYOUT_5POINT0_BACK: s->channel_mode = AC3_CHMODE_3F2R; break; |
||

1597 | ```
default:
``` |
||

1598 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1599 | e77fd066 | Justin Ruggles | } |

1600 | |||

1601 | s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe_on]; |
||

1602 | *channel_layout = ch_layout; |
||

1603 | ```
if (s->lfe_on)
``` |
||

1604 | *channel_layout |= AV_CH_LOW_FREQUENCY; |
||

1605 | |||

1606 | return 0; |
||

1607 | } |
||

1608 | |||

1609 | 2f8ae522 | Justin Ruggles | |

1610 | 8f60f70d | Justin Ruggles | static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) |

1611 | e77fd066 | Justin Ruggles | { |

1612 | ddf63d37 | Justin Ruggles | ```
int i, ret;
``` |

1613 | e77fd066 | Justin Ruggles | |

1614 | e0685bc9 | Justin Ruggles | ```
/* validate channel layout */
``` |

1615 | e77fd066 | Justin Ruggles | ```
if (!avctx->channel_layout) {
``` |

1616 | ```
av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
``` |
||

1617 | ```
"encoder will guess the layout, but it "
``` |
||

1618 | ```
"might be incorrect.\n");
``` |
||

1619 | } |
||

1620 | ddf63d37 | Justin Ruggles | ret = set_channel_info(s, avctx->channels, &avctx->channel_layout); |

1621 | ```
if (ret) {
``` |
||

1622 | e77fd066 | Justin Ruggles | ```
av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n");
``` |

1623 | ddf63d37 | Justin Ruggles | ```
return ret;
``` |

1624 | e77fd066 | Justin Ruggles | } |

1625 | |||

1626 | e0685bc9 | Justin Ruggles | ```
/* validate sample rate */
``` |

1627 | 99ca4f73 | Justin Ruggles | for (i = 0; i < 9; i++) { |

1628 | if ((ff_ac3_sample_rate_tab[i / 3] >> (i % 3)) == avctx->sample_rate) |
||

1629 | ```
break;
``` |
||

1630 | e77fd066 | Justin Ruggles | } |

1631 | 99ca4f73 | Justin Ruggles | if (i == 9) { |

1632 | ddf63d37 | Justin Ruggles | ```
av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
``` |

1633 | ```
return AVERROR(EINVAL);
``` |
||

1634 | 99ca4f73 | Justin Ruggles | } |

1635 | 1607db0a | Justin Ruggles | s->sample_rate = avctx->sample_rate; |

1636 | 99ca4f73 | Justin Ruggles | ```
s->bit_alloc.sr_shift = i % 3;
``` |

1637 | ```
s->bit_alloc.sr_code = i / 3;
``` |
||

1638 | e77fd066 | Justin Ruggles | |

1639 | e0685bc9 | Justin Ruggles | ```
/* validate bit rate */
``` |

1640 | e77fd066 | Justin Ruggles | for (i = 0; i < 19; i++) { |

1641 | 1607db0a | Justin Ruggles | if ((ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift)*1000 == avctx->bit_rate) |

1642 | e77fd066 | Justin Ruggles | ```
break;
``` |

1643 | } |
||

1644 | ddf63d37 | Justin Ruggles | if (i == 19) { |

1645 | ```
av_log(avctx, AV_LOG_ERROR, "invalid bit rate\n");
``` |
||

1646 | ```
return AVERROR(EINVAL);
``` |
||

1647 | } |
||

1648 | 1607db0a | Justin Ruggles | s->bit_rate = avctx->bit_rate; |

1649 | e77fd066 | Justin Ruggles | ```
s->frame_size_code = i << 1;
``` |

1650 | 8f60f70d | Justin Ruggles | |

1651 | e62ef8f2 | Justin Ruggles | ```
/* validate cutoff */
``` |

1652 | if (avctx->cutoff < 0) { |
||

1653 | ```
av_log(avctx, AV_LOG_ERROR, "invalid cutoff frequency\n");
``` |
||

1654 | ```
return AVERROR(EINVAL);
``` |
||

1655 | } |
||

1656 | s->cutoff = avctx->cutoff; |
||

1657 | if (s->cutoff > (s->sample_rate >> 1)) |
||

1658 | ```
s->cutoff = s->sample_rate >> 1;
``` |
||

1659 | |||

1660 | 8f60f70d | Justin Ruggles | return 0; |

1661 | } |
||

1662 | |||

1663 | |||

1664 | ```
/**
``` |
||

1665 | 282255bb | Justin Ruggles | ```
* Set bandwidth for all channels.
``` |

1666 | ```
* The user can optionally supply a cutoff frequency. Otherwise an appropriate
``` |
||

1667 | ```
* default value will be used.
``` |
||

1668 | ```
*/
``` |
||

1669 | e62ef8f2 | Justin Ruggles | static av_cold void set_bandwidth(AC3EncodeContext *s) |

1670 | 282255bb | Justin Ruggles | { |

1671 | ```
int ch, bw_code;
``` |
||

1672 | |||

1673 | e62ef8f2 | Justin Ruggles | ```
if (s->cutoff) {
``` |

1674 | 282255bb | Justin Ruggles | ```
/* calculate bandwidth based on user-specified cutoff frequency */
``` |

1675 | ```
int fbw_coeffs;
``` |
||

1676 | e62ef8f2 | Justin Ruggles | ```
fbw_coeffs = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate;
``` |

1677 | 282255bb | Justin Ruggles | bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); |

1678 | ```
} else {
``` |
||

1679 | ```
/* use default bandwidth setting */
``` |
||

1680 | ```
/* XXX: should compute the bandwidth according to the frame
``` |
||

1681 | ```
size, so that we avoid annoying high frequency artifacts */
``` |
||

1682 | ```
bw_code = 50;
``` |
||

1683 | } |
||

1684 | |||

1685 | ```
/* set number of coefficients for each channel */
``` |
||

1686 | for (ch = 0; ch < s->fbw_channels; ch++) { |
||

1687 | s->bandwidth_code[ch] = bw_code; |
||

1688 | s->nb_coefs[ch] = bw_code * 3 + 73; |
||

1689 | } |
||

1690 | ```
if (s->lfe_on)
``` |
||

1691 | s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */ |
||

1692 | } |
||

1693 | |||

1694 | |||

1695 | 171bc51c | Justin Ruggles | static av_cold int allocate_buffers(AVCodecContext *avctx) |

1696 | { |
||

1697 | e8d21fba | Justin Ruggles | ```
int blk, ch;
``` |

1698 | 171bc51c | Justin Ruggles | AC3EncodeContext *s = avctx->priv_data; |

1699 | |||

1700 | e8d21fba | Justin Ruggles | ```
FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),
``` |

1701 | alloc_fail); |
||

1702 | for (ch = 0; ch < s->channels; ch++) { |
||

1703 | FF_ALLOCZ_OR_GOTO(avctx, s->planar_samples[ch], |
||

1704 | ```
(AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
``` |
||

1705 | alloc_fail); |
||

1706 | } |
||

1707 | 171bc51c | Justin Ruggles | FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * s->channels * |

1708 | ```
AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail);
``` |
||

1709 | FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1710 | ```
AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail);
``` |
||

1711 | b6f6204d | Justin Ruggles | FF_ALLOC_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * s->channels * |

1712 | ```
AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail);
``` |
||

1713 | FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1714 | ```
AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail);
``` |
||

1715 | FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1716 | 128 * sizeof(*s->grouped_exp_buffer), alloc_fail); |
||

1717 | FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1718 | ```
AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail);
``` |
||

1719 | FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1720 | 64 * sizeof(*s->band_psd_buffer), alloc_fail); |
||

1721 | FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1722 | 64 * sizeof(*s->mask_buffer), alloc_fail); |
||

1723 | FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1724 | ```
AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail);
``` |
||

1725 | 171bc51c | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

1726 | AC3Block *block = &s->blocks[blk]; |
||

1727 | ```
FF_ALLOC_OR_GOTO(avctx, block->bap, s->channels * sizeof(*block->bap),
``` |
||

1728 | alloc_fail); |
||

1729 | b6f6204d | Justin Ruggles | ```
FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, s->channels * sizeof(*block->mdct_coef),
``` |

1730 | alloc_fail); |
||

1731 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->exp, s->channels * sizeof(*block->exp),
``` |
||

1732 | alloc_fail); |
||

1733 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->grouped_exp, s->channels * sizeof(*block->grouped_exp),
``` |
||

1734 | alloc_fail); |
||

1735 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->psd, s->channels * sizeof(*block->psd),
``` |
||

1736 | alloc_fail); |
||

1737 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->band_psd, s->channels * sizeof(*block->band_psd),
``` |
||

1738 | alloc_fail); |
||

1739 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->mask, s->channels * sizeof(*block->mask),
``` |
||

1740 | alloc_fail); |
||

1741 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->qmant, s->channels * sizeof(*block->qmant),
``` |
||

1742 | alloc_fail); |
||

1743 | |||

1744 | for (ch = 0; ch < s->channels; ch++) { |
||

1745 | 7cc4be58 | Justin Ruggles | ```
/* arrangement: block, channel, coeff */
``` |

1746 | b6f6204d | Justin Ruggles | block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |

1747 | block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1748 | ```
block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * s->channels + ch)];
``` |
||

1749 | block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1750 | ```
block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * s->channels + ch)];
``` |
||

1751 | ```
block->mask[ch] = &s->mask_buffer [64 * (blk * s->channels + ch)];
``` |
||

1752 | block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1753 | 7cc4be58 | Justin Ruggles | |

1754 | ```
/* arrangement: channel, block, coeff */
``` |
||

1755 | block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; |
||

1756 | b6f6204d | Justin Ruggles | } |

1757 | 171bc51c | Justin Ruggles | } |

1758 | |||

1759 | ac05f903 | Justin Ruggles | ```
if (CONFIG_AC3ENC_FLOAT) {
``` |

1760 | FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1761 | ```
AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);
``` |
||

1762 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

1763 | AC3Block *block = &s->blocks[blk]; |
||

1764 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * |
||

1765 | ```
sizeof(*block->fixed_coef), alloc_fail);
``` |
||

1766 | for (ch = 0; ch < s->channels; ch++) |
||

1767 | block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1768 | } |
||

1769 | ```
} else {
``` |
||

1770 | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |
||

1771 | AC3Block *block = &s->blocks[blk]; |
||

1772 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * |
||

1773 | ```
sizeof(*block->fixed_coef), alloc_fail);
``` |
||

1774 | for (ch = 0; ch < s->channels; ch++) |
||

1775 | block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; |
||

1776 | } |
||

1777 | } |
||

1778 | |||

1779 | 171bc51c | Justin Ruggles | return 0; |

1780 | ```
alloc_fail:
``` |
||

1781 | ```
return AVERROR(ENOMEM);
``` |
||

1782 | } |
||

1783 | |||

1784 | |||

1785 | 282255bb | Justin Ruggles | ```
/**
``` |

1786 | 8f60f70d | Justin Ruggles | ```
* Initialize the encoder.
``` |

1787 | ```
*/
``` |
||

1788 | static av_cold int ac3_encode_init(AVCodecContext *avctx) |
||

1789 | { |
||

1790 | AC3EncodeContext *s = avctx->priv_data; |
||

1791 | a81d7c6a | Justin Ruggles | ```
int ret, frame_size_58;
``` |

1792 | 8f60f70d | Justin Ruggles | |

1793 | avctx->frame_size = AC3_FRAME_SIZE; |
||

1794 | |||

1795 | 4c57cde9 | Justin Ruggles | ff_ac3_common_init(); |

1796 | 8f60f70d | Justin Ruggles | |

1797 | ret = validate_options(avctx, s); |
||

1798 | ```
if (ret)
``` |
||

1799 | ```
return ret;
``` |
||

1800 | |||

1801 | e35c984a | Justin Ruggles | ```
s->bitstream_id = 8 + s->bit_alloc.sr_shift;
``` |

1802 | s->bitstream_mode = 0; /* complete main audio service */ |
||

1803 | |||

1804 | 427e2293 | Justin Ruggles | ```
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
``` |

1805 | e77fd066 | Justin Ruggles | ```
s->bits_written = 0;
``` |

1806 | ```
s->samples_written = 0;
``` |
||

1807 | s->frame_size = s->frame_size_min; |
||

1808 | |||

1809 | a81d7c6a | Justin Ruggles | ```
/* calculate crc_inv for both possible frame sizes */
``` |

1810 | frame_size_58 = (( s->frame_size >> 2) + ( s->frame_size >> 4)) << 1; |
||

1811 | s->crc_inv[0] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); |
||

1812 | if (s->bit_alloc.sr_code == 1) { |
||

1813 | frame_size_58 = (((s->frame_size+2) >> 2) + ((s->frame_size+2) >> 4)) << 1; |
||

1814 | s->crc_inv[1] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); |
||

1815 | } |
||

1816 | |||

1817 | e62ef8f2 | Justin Ruggles | set_bandwidth(s); |

1818 | e77fd066 | Justin Ruggles | |

1819 | dc7e07ac | Justin Ruggles | rematrixing_init(s); |

1820 | |||

1821 | e86ea34d | Justin Ruggles | exponent_init(s); |

1822 | |||

1823 | 793bbf95 | Justin Ruggles | bit_alloc_init(s); |

1824 | e77fd066 | Justin Ruggles | |

1825 | 14166a6d | Justin Ruggles | ```
ret = mdct_init(avctx, &s->mdct, 9);
``` |

1826 | 7786c384 | Justin Ruggles | ```
if (ret)
``` |

1827 | 89bedc4d | Justin Ruggles | ```
goto init_fail;
``` |

1828 | e77fd066 | Justin Ruggles | |

1829 | 171bc51c | Justin Ruggles | ret = allocate_buffers(avctx); |

1830 | 7786c384 | Justin Ruggles | ```
if (ret)
``` |

1831 | 89bedc4d | Justin Ruggles | ```
goto init_fail;
``` |

1832 | 171bc51c | Justin Ruggles | |

1833 | e77fd066 | Justin Ruggles | avctx->coded_frame= avcodec_alloc_frame(); |

1834 | |||

1835 | 8846ee54 | Justin Ruggles | dsputil_init(&s->dsp, avctx); |

1836 | 0f999cfd | Justin Ruggles | ff_ac3dsp_init(&s->ac3dsp, avctx->flags & CODEC_FLAG_BITEXACT); |

1837 | 8846ee54 | Justin Ruggles | |

1838 | e77fd066 | Justin Ruggles | return 0; |

1839 | 89bedc4d | Justin Ruggles | ```
init_fail:
``` |

1840 | ac3_encode_close(avctx); |
||

1841 | ```
return ret;
``` |
||

1842 | e77fd066 | Justin Ruggles | } |