## ffmpeg / libavcodec / ac3enc.c @ 3b924294

History | View | Annotate | Download (58.3 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 | b78e7197 | Diego Biurrun | ```
* This file is part of FFmpeg.
``` |

8 | ```
*
``` |
||

9 | ```
* FFmpeg 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 | b78e7197 | Diego Biurrun | ```
* FFmpeg 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 | b78e7197 | Diego Biurrun | ```
* License along with FFmpeg; 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 | 22c0b03c | Justin Ruggles | |

31 | 63e8d976 | Stefano Sabatini | #include "libavcore/audioconvert.h" |

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

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

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

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

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

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

38 | 6107fa87 | Fabrice Bellard | |

39 | 2f8ae522 | Justin Ruggles | |

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

41 | #define CONFIG_AC3ENC_FLOAT 0 |
||

42 | ```
#endif
``` |
||

43 | |||

44 | |||

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

46 | #define AC3_MAX_EXP_GROUPS 85 |
||

47 | |||

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

49 | #define AC3_REMATRIXING_IS_STATIC 0x1 |
||

50 | #define AC3_REMATRIXING_SUMS 0 |
||

51 | #define AC3_REMATRIXING_NONE 1 |
||

52 | #define AC3_REMATRIXING_ALWAYS 3 |
||

53 | |||

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

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

56 | |||

57 | 0cbd5ff7 | Justin Ruggles | |

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

59 | #include "ac3enc_float.h" |
||

60 | ```
#else
``` |
||

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

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

63 | e77fd066 | Justin Ruggles | |

64 | 2f8ae522 | Justin Ruggles | |

65 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

67 | ```
*/
``` |
||

68 | typedef struct AC3Block { |
||

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

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

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

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

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

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

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

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

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

78 | ```
int8_t exp_shift[AC3_MAX_CHANNELS]; ///< exponent shift values
``` |
||

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

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

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

82 | |||

83 | ```
/**
``` |
||

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

85 | ```
*/
``` |
||

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

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

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

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

90 | 7e5a4bf8 | Justin Ruggles | |

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

92 | |||

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

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

95 | 7e5a4bf8 | Justin Ruggles | |

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

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

98 | 7e5a4bf8 | Justin Ruggles | |

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

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

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

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

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

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

105 | 7e5a4bf8 | Justin Ruggles | |

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

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

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

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

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

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

112 | 7e5a4bf8 | Justin Ruggles | |

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

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

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

116 | 115329f1 | Diego Biurrun | |

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

118 | |||

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

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

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

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

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

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

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

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

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

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

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

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

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

132 | 7e5a4bf8 | Justin Ruggles | |

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

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

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

136 | 7e5a4bf8 | Justin Ruggles | |

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

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

139 | uint8_t *bap1_buffer; |
||

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

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

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

143 | uint8_t *grouped_exp_buffer; |
||

144 | int16_t *psd_buffer; |
||

145 | int16_t *band_psd_buffer; |
||

146 | int16_t *mask_buffer; |
||

147 | uint16_t *qmant_buffer; |
||

148 | aa645b98 | Justin Ruggles | |

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

150 | |||

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

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

153 | de6d9b64 | Fabrice Bellard | |

154 | 2f8ae522 | Justin Ruggles | |

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

156 | ad6b2c1f | Justin Ruggles | |

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

158 | |||

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

160 | ```
int nbits);
``` |
||

161 | |||

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

163 | |||

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

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

166 | |||

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

168 | |||

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

170 | |||

171 | ad6b2c1f | Justin Ruggles | |

172 | e86ea34d | Justin Ruggles | ```
/**
``` |

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

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

175 | ```
*/
``` |
||

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

177 | e86ea34d | Justin Ruggles | |

178 | 2f8ae522 | Justin Ruggles | |

179 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

181 | ```
*/
``` |
||

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

183 | AV_CH_LAYOUT_MONO, |
||

184 | AV_CH_LAYOUT_STEREO, |
||

185 | AV_CH_LAYOUT_2_1, |
||

186 | AV_CH_LAYOUT_SURROUND, |
||

187 | AV_CH_LAYOUT_2_2, |
||

188 | AV_CH_LAYOUT_QUAD, |
||

189 | AV_CH_LAYOUT_4POINT0, |
||

190 | AV_CH_LAYOUT_5POINT0, |
||

191 | AV_CH_LAYOUT_5POINT0_BACK, |
||

192 | (AV_CH_LAYOUT_MONO | AV_CH_LOW_FREQUENCY), |
||

193 | (AV_CH_LAYOUT_STEREO | AV_CH_LOW_FREQUENCY), |
||

194 | (AV_CH_LAYOUT_2_1 | AV_CH_LOW_FREQUENCY), |
||

195 | (AV_CH_LAYOUT_SURROUND | AV_CH_LOW_FREQUENCY), |
||

196 | (AV_CH_LAYOUT_2_2 | AV_CH_LOW_FREQUENCY), |
||

197 | (AV_CH_LAYOUT_QUAD | AV_CH_LOW_FREQUENCY), |
||

198 | (AV_CH_LAYOUT_4POINT0 | AV_CH_LOW_FREQUENCY), |
||

199 | AV_CH_LAYOUT_5POINT1, |
||

200 | AV_CH_LAYOUT_5POINT1_BACK, |
||

201 | ```
0
``` |
||

202 | }; |
||

203 | |||

204 | |||

205 | ```
/**
``` |
||

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

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

208 | ```
*/
``` |
||

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

210 | { |
||

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

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

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

214 | } |
||

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

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

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

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

219 | } |
||

220 | |||

221 | |||

222 | ```
/**
``` |
||

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

224 | ```
* Channels are reordered from FFmpeg's default order to AC-3 order.
``` |
||

225 | ```
*/
``` |
||

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

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

228 | 4acc790f | Justin Ruggles | { |

229 | ```
int ch, i;
``` |
||

230 | |||

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

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

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

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

235 | |||

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

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

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

239 | 4acc790f | Justin Ruggles | |

240 | ```
/* deinterleave */
``` |
||

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

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

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

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

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

246 | } |
||

247 | } |
||

248 | } |
||

249 | |||

250 | |||

251 | ```
/**
``` |
||

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

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

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

255 | ```
*/
``` |
||

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

257 | 0a0a8500 | Justin Ruggles | { |

258 | ```
int blk, ch;
``` |
||

259 | |||

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

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

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

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

264 | 0a0a8500 | Justin Ruggles | |

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

266 | 0a0a8500 | Justin Ruggles | |

267 | 5901cebe | Justin Ruggles | block->exp_shift[ch] = normalize_samples(s); |

268 | 0a0a8500 | Justin Ruggles | |

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

270 | 0a0a8500 | Justin Ruggles | } |

271 | } |
||

272 | } |
||

273 | |||

274 | |||

275 | ```
/**
``` |
||

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

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

278 | ```
*/
``` |
||

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

280 | { |
||

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

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

283 | ```
else
``` |
||

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

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

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

287 | |||

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

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

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

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

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

293 | } |
||

294 | } |
||

295 | |||

296 | |||

297 | ```
/**
``` |
||

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

299 | ```
*/
``` |
||

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

301 | { |
||

302 | ```
int nb_coefs;
``` |
||

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

304 | AC3Block *block, *block0; |
||

305 | |||

306 | ```
if (s->rematrixing & AC3_REMATRIXING_IS_STATIC)
``` |
||

307 | ```
return;
``` |
||

308 | |||

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

310 | |||

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

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

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

314 | for (bnd = 0; bnd < 4; bnd++) { |
||

315 | ```
/* calculate calculate sum of squared coeffs for one band in one block */
``` |
||

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

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

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

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

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

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

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

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

324 | ```
sum[0] += lt * lt;
``` |
||

325 | ```
sum[1] += rt * rt;
``` |
||

326 | ```
sum[2] += md * md;
``` |
||

327 | ```
sum[3] += sd * sd;
``` |
||

328 | } |
||

329 | |||

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

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

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

333 | ```
else
``` |
||

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

335 | |||

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

337 | ```
if (blk &&
``` |
||

338 | !block->new_rematrixing_strategy && |
||

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

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

341 | } |
||

342 | } |
||

343 | block0 = block; |
||

344 | } |
||

345 | } |
||

346 | |||

347 | |||

348 | ```
/**
``` |
||

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

350 | ```
*/
``` |
||

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

352 | { |
||

353 | ```
int nb_coefs;
``` |
||

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

355 | ```
int start, end;
``` |
||

356 | uint8_t *flags; |
||

357 | |||

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

359 | ```
return;
``` |
||

360 | |||

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

362 | |||

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

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

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

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

367 | for (bnd = 0; bnd < 4; bnd++) { |
||

368 | ```
if (flags[bnd]) {
``` |
||

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

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

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

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

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

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

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

376 | } |
||

377 | } |
||

378 | } |
||

379 | } |
||

380 | } |
||

381 | |||

382 | |||

383 | ```
/**
``` |
||

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

385 | ```
*/
``` |
||

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

387 | { |
||

388 | ```
int i;
``` |
||

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

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

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

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

393 | } |
||

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

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

396 | e86ea34d | Justin Ruggles | } |

397 | |||

398 | |||

399 | ```
/**
``` |
||

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

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

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

403 | ```
*/
``` |
||

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

405 | dfdf73eb | Justin Ruggles | { |

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

407 | |||

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

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

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

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

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

413 | 9be52d48 | Justin Ruggles | ```
int exp_shift = block->exp_shift[ch];
``` |

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

415 | ```
int e;
``` |
||

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

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

418 | ```
e = 24;
``` |
||

419 | ```
else {
``` |
||

420 | 9be52d48 | Justin Ruggles | ```
e = 23 - av_log2(v) + exp_shift;
``` |

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

422 | ```
e = 24;
``` |
||

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

424 | dfdf73eb | Justin Ruggles | } |

425 | } |
||

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

427 | dfdf73eb | Justin Ruggles | } |

428 | } |
||

429 | } |
||

430 | } |
||

431 | |||

432 | |||

433 | ```
/**
``` |
||

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

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

436 | ```
*/
``` |
||

437 | 6a988808 | Justin Ruggles | #define EXP_DIFF_THRESHOLD 1000 |

438 | |||

439 | 2f8ae522 | Justin Ruggles | |

440 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

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

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

445 | de6d9b64 | Fabrice Bellard | { |

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

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

448 | 115329f1 | Diego Biurrun | |

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

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

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

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

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

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

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

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

457 | de6d9b64 | Fabrice Bellard | ```
else
``` |

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

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

460 | de6d9b64 | Fabrice Bellard | } |

461 | f9f69028 | Justin Ruggles | emms_c(); |

462 | 30b68f33 | Zdenek Kabelac | |

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

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

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

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

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

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

469 | ce67b7cd | Justin Ruggles | blk1++; |

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

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

472 | de6d9b64 | Fabrice Bellard | case 2: |

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

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

475 | de6d9b64 | Fabrice Bellard | } |

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

477 | de6d9b64 | Fabrice Bellard | } |

478 | } |
||

479 | |||

480 | 2f8ae522 | Justin Ruggles | |

481 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

484 | dfdf73eb | Justin Ruggles | ```
*/
``` |

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

486 | dfdf73eb | Justin Ruggles | { |

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

488 | dfdf73eb | Justin Ruggles | |

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

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

491 | d7da8080 | Justin Ruggles | } |

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

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

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

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

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

497 | dfdf73eb | Justin Ruggles | } |

498 | } |
||

499 | |||

500 | |||

501 | ```
/**
``` |
||

502 | c36ce0f8 | Justin Ruggles | ```
* Set each encoded exponent in a block to the minimum of itself and the
``` |

503 | 964f2cf2 | Justin Ruggles | ```
* exponents in the same frequency bin of up to 5 following blocks.
``` |

504 | c36ce0f8 | Justin Ruggles | ```
*/
``` |

505 | 964f2cf2 | Justin Ruggles | static void exponent_min(uint8_t *exp, int num_reuse_blocks, int nb_coefs) |

506 | de6d9b64 | Fabrice Bellard | { |

507 | 964f2cf2 | Justin Ruggles | ```
int blk, i;
``` |

508 | |||

509 | ```
if (!num_reuse_blocks)
``` |
||

510 | ```
return;
``` |
||

511 | |||

512 | for (i = 0; i < nb_coefs; i++) { |
||

513 | uint8_t min_exp = *exp; |
||

514 | uint8_t *exp1 = exp + AC3_MAX_COEFS; |
||

515 | for (blk = 0; blk < num_reuse_blocks; blk++) { |
||

516 | uint8_t next_exp = *exp1; |
||

517 | ```
if (next_exp < min_exp)
``` |
||

518 | min_exp = next_exp; |
||

519 | exp1 += AC3_MAX_COEFS; |
||

520 | } |
||

521 | *exp++ = min_exp; |
||

522 | de6d9b64 | Fabrice Bellard | } |

523 | } |
||

524 | 115329f1 | Diego Biurrun | |

525 | 2f8ae522 | Justin Ruggles | |

526 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

527 | ```
* Update the exponents so that they are the ones the decoder will decode.
``` |
||

528 | ```
*/
``` |
||

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

530 | de6d9b64 | Fabrice Bellard | { |

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

532 | de6d9b64 | Fabrice Bellard | |

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

534 | de6d9b64 | Fabrice Bellard | |

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

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

537 | ```
case EXP_D25:
``` |
||

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

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

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

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

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

543 | ```
k += 2;
``` |
||

544 | de6d9b64 | Fabrice Bellard | } |

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

546 | ```
case EXP_D45:
``` |
||

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

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

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

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

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

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

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

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

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

556 | ```
k += 4;
``` |
||

557 | } |
||

558 | ```
break;
``` |
||

559 | 27af78cf | Justin Ruggles | } |

560 | de6d9b64 | Fabrice Bellard | |

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

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

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

564 | de6d9b64 | Fabrice Bellard | |

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

566 | ```
differentially encoded */
``` |
||

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

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

569 | cdedf7e6 | Justin Ruggles | i--; |

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

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

572 | e44cad52 | Jeff Muizelaar | |

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

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

575 | ```
case EXP_D25:
``` |
||

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

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

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

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

580 | } |
||

581 | ```
break;
``` |
||

582 | ```
case EXP_D45:
``` |
||

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

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

585 | ```
k -= 4;
``` |
||

586 | } |
||

587 | ```
break;
``` |
||

588 | de6d9b64 | Fabrice Bellard | } |

589 | } |
||

590 | |||

591 | 2f8ae522 | Justin Ruggles | |

592 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

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

596 | ```
* encoded.
``` |
||

597 | ```
*/
``` |
||

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

599 | dfdf73eb | Justin Ruggles | { |

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

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

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

603 | dfdf73eb | Justin Ruggles | |

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

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

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

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

608 | |||

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

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

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

612 | 964f2cf2 | Justin Ruggles | |

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

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

615 | dfdf73eb | Justin Ruggles | blk1++; |

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

617 | |||

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

619 | exponent_min(exp, num_reuse_blocks, nb_coefs); |
||

620 | |||

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

622 | |||

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

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

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

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

627 | exp1 += AC3_MAX_COEFS; |
||

628 | blk++; |
||

629 | dfdf73eb | Justin Ruggles | } |

630 | blk = blk1; |
||

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

632 | dfdf73eb | Justin Ruggles | } |

633 | } |
||

634 | f94bacc5 | Justin Ruggles | } |

635 | |||

636 | |||

637 | ```
/**
``` |
||

638 | ```
* Group exponents.
``` |
||

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

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

641 | ```
*/
``` |
||

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

643 | f94bacc5 | Justin Ruggles | { |

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

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

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

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

648 | ```
int exp0, exp1;
``` |
||

649 | |||

650 | ```
bit_count = 0;
``` |
||

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

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

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

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

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

656 | f94bacc5 | Justin Ruggles | ```
continue;
``` |

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

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

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

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

661 | f94bacc5 | Justin Ruggles | |

662 | ```
/* DC exponent */
``` |
||

663 | exp1 = *p++; |
||

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

665 | f94bacc5 | Justin Ruggles | |

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

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

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

669 | exp0 = exp1; |
||

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

671 | p += group_size; |
||

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

673 | |||

674 | exp0 = exp1; |
||

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

676 | p += group_size; |
||

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

678 | |||

679 | exp0 = exp1; |
||

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

681 | p += group_size; |
||

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

683 | |||

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

685 | f94bacc5 | Justin Ruggles | } |

686 | } |
||

687 | } |
||

688 | dfdf73eb | Justin Ruggles | |

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

690 | dfdf73eb | Justin Ruggles | } |

691 | |||

692 | |||

693 | ```
/**
``` |
||

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

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

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

697 | ```
*/
``` |
||

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

699 | dfdf73eb | Justin Ruggles | { |

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

701 | dfdf73eb | Justin Ruggles | |

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

703 | dfdf73eb | Justin Ruggles | |

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

705 | f94bacc5 | Justin Ruggles | |

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

707 | dfdf73eb | Justin Ruggles | } |

708 | |||

709 | |||

710 | ```
/**
``` |
||

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

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

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

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

715 | { |
||

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

717 | ```
int blk;
``` |
||

718 | ```
int frame_bits;
``` |
||

719 | |||

720 | ```
/* assumptions:
``` |
||

721 | ```
* no dynamic range codes
``` |
||

722 | ```
* no channel coupling
``` |
||

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

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

725 | ```
* no delta bit allocation
``` |
||

726 | ```
* no skipped data
``` |
||

727 | ```
* no auxilliary data
``` |
||

728 | ```
*/
``` |
||

729 | |||

730 | ```
/* header size */
``` |
||

731 | ```
frame_bits = 65;
``` |
||

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

733 | |||

734 | ```
/* audio blocks */
``` |
||

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

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

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

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

739 | } |
||

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

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

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

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

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

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

746 | } |
||

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

748 | ```
/* bit alloc info */
``` |
||

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

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

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

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

753 | |||

754 | ```
/* auxdatae, crcrsv */
``` |
||

755 | ```
frame_bits += 2;
``` |
||

756 | |||

757 | ```
/* CRC */
``` |
||

758 | ```
frame_bits += 16;
``` |
||

759 | |||

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

761 | } |
||

762 | |||

763 | |||

764 | ```
/**
``` |
||

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

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

767 | ```
*/
``` |
||

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

769 | { |
||

770 | ```
int ch;
``` |
||

771 | |||

772 | ```
/* init default parameters */
``` |
||

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

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

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

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

777 | 793bbf95 | Justin Ruggles | ```
s->floor_code = 4;
``` |

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

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

780 | |||

781 | ```
/* initial snr offset */
``` |
||

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

783 | |||

784 | ```
/* compute real values */
``` |
||

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

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

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

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

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

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

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

792 | e7536ac5 | Justin Ruggles | |

793 | count_frame_bits_fixed(s); |
||

794 | 793bbf95 | Justin Ruggles | } |

795 | |||

796 | |||

797 | ```
/**
``` |
||

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

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

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

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

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

803 | 8999944e | Justin Ruggles | { |

804 | ```
int blk, ch;
``` |
||

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

806 | 8999944e | Justin Ruggles | |

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

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

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

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

811 | ```
frame_bits += 4;
``` |
||

812 | } |
||

813 | |||

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

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

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

817 | } |
||

818 | } |
||

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

820 | 8999944e | Justin Ruggles | } |

821 | |||

822 | |||

823 | ```
/**
``` |
||

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

825 | ```
*/
``` |
||

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

827 | de6d9b64 | Fabrice Bellard | { |

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

829 | de6d9b64 | Fabrice Bellard | |

830 | ```
bits = 0;
``` |
||

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

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

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

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

835 | mant_cnt[b]++; |
||

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

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

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

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

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

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

842 | de6d9b64 | Fabrice Bellard | } |

843 | } |
||

844 | ```
return bits;
``` |
||

845 | } |
||

846 | |||

847 | |||

848 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

850 | ```
*/
``` |
||

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

852 | { |
||

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

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

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

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

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

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

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

860 | ```
return bits;
``` |
||

861 | } |
||

862 | |||

863 | |||

864 | ```
/**
``` |
||

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

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

867 | ```
*/
``` |
||

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

869 | bbd16dea | Justin Ruggles | { |

870 | ```
int blk, ch;
``` |
||

871 | |||

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

888 | bbd16dea | Justin Ruggles | } |

889 | } |
||

890 | } |
||

891 | } |
||

892 | |||

893 | 2f8ae522 | Justin Ruggles | |

894 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

897 | ```
*/
``` |
||

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

899 | { |
||

900 | ```
int blk, ch;
``` |
||

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

902 | ```
return;
``` |
||

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

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

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

906 | } |
||

907 | } |
||

908 | } |
||

909 | |||

910 | |||

911 | ```
/**
``` |
||

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

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

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

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

916 | ```
* is used.
``` |
||

917 | c36ce0f8 | Justin Ruggles | ```
*/
``` |

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

919 | de6d9b64 | Fabrice Bellard | { |

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

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

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

923 | 319708da | Justin Ruggles | |

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

925 | de6d9b64 | Fabrice Bellard | |

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

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

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

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

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

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

932 | ```
// compute_mantissa_size_final
``` |
||

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

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

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

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

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

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

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

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

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

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

943 | ```
} else {
``` |
||

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

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

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

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

948 | 795063db | Justin Ruggles | } |

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

950 | de6d9b64 | Fabrice Bellard | } |

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

952 | de6d9b64 | Fabrice Bellard | } |

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

954 | de6d9b64 | Fabrice Bellard | } |

955 | |||

956 | 2f8ae522 | Justin Ruggles | |

957 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

960 | c36ce0f8 | Justin Ruggles | ```
*/
``` |

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

962 | de6d9b64 | Fabrice Bellard | { |

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

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

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

966 | de6d9b64 | Fabrice Bellard | |

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

968 | 7da4dc17 | Justin Ruggles | |

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

970 | 7da4dc17 | Justin Ruggles | |

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

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

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

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

975 | return 0; |
||

976 | } |
||

977 | |||

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

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

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

981 | 7da4dc17 | Justin Ruggles | } |

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

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

984 | 7da4dc17 | Justin Ruggles | |

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

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

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

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

989 | snr_offset += snr_incr; |
||

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

991 | } |
||

992 | de6d9b64 | Fabrice Bellard | } |

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

994 | reset_block_bap(s); |
||

995 | 115329f1 | Diego Biurrun | |

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

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

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

999 | 22c0b03c | Justin Ruggles | |

1000 | de6d9b64 | Fabrice Bellard | return 0; |

1001 | } |
||

1002 | |||

1003 | 2f8ae522 | Justin Ruggles | |

1004 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

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

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

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

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

1010 | ```
*/
``` |
||

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

1012 | { |
||

1013 | ```
int ch, blk;
``` |
||

1014 | |||

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

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

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

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

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

1020 | } |
||

1021 | } |
||

1022 | } |
||

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

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

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

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

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

1028 | } |
||

1029 | } |
||

1030 | } |
||

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

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

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

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

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

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

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

1038 | } |
||

1039 | } |
||

1040 | } |
||

1041 | return -1; |
||

1042 | } |
||

1043 | |||

1044 | |||

1045 | ```
/**
``` |
||

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

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

1048 | ```
* have been downgraded.
``` |
||

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

1050 | ```
*/
``` |
||

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

1052 | { |
||

1053 | ```
int ch;
``` |
||

1054 | |||

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

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

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

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

1059 | } |
||

1060 | return 0; |
||

1061 | } |
||

1062 | return -1; |
||

1063 | } |
||

1064 | |||

1065 | |||

1066 | ```
/**
``` |
||

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

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

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

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

1071 | ```
*/
``` |
||

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

1073 | { |
||

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

1075 | |||

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

1077 | |||

1078 | bit_alloc_masking(s); |
||

1079 | |||

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

1081 | ```
while (ret) {
``` |
||

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

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

1084 | extract_exponents(s); |
||

1085 | encode_exponents(s); |
||

1086 | group_exponents(s); |
||

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

1088 | ```
continue;
``` |
||

1089 | } |
||

1090 | |||

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

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

1093 | ```
frequency */
``` |
||

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

1095 | process_exponents(s); |
||

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

1097 | ```
continue;
``` |
||

1098 | } |
||

1099 | |||

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

1101 | ```
break;
``` |
||

1102 | } |
||

1103 | |||

1104 | ```
return ret;
``` |
||

1105 | cb6247cb | Justin Ruggles | } |

1106 | |||

1107 | |||

1108 | ```
/**
``` |
||

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

1110 | ```
*/
``` |
||

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

1112 | { |
||

1113 | ```
int v;
``` |
||

1114 | |||

1115 | if (c >= 0) { |
||

1116 | 8d67072f | Fabrice Bellard | ```
v = (levels * (c << e)) >> 24;
``` |

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

1118 | de6d9b64 | Fabrice Bellard | ```
v = (levels >> 1) + v;
``` |

1119 | ```
} else {
``` |
||

1120 | 8d67072f | Fabrice Bellard | ```
v = (levels * ((-c) << e)) >> 24;
``` |

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

1122 | de6d9b64 | Fabrice Bellard | ```
v = (levels >> 1) - v;
``` |

1123 | } |
||

1124 | 2d82d9b1 | Justin Ruggles | ```
assert(v >= 0 && v < levels);
``` |

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

1126 | } |
||

1127 | |||

1128 | 2f8ae522 | Justin Ruggles | |

1129 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

1131 | ```
*/
``` |
||

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

1133 | { |
||

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

1135 | |||

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

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

1138 | v = c << lshift; |
||

1139 | ```
else
``` |
||

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

1141 | ```
/* rounding */
``` |
||

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

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

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

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

1146 | assert(v >= -m); |
||

1147 | return v & ((1 << qbits)-1); |
||

1148 | } |
||

1149 | |||

1150 | 2f8ae522 | Justin Ruggles | |

1151 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

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

1153 | ```
*/
``` |
||

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

1155 | b5293036 | Justin Ruggles | int8_t exp_shift, uint8_t *exp, |

1156 | ```
uint8_t *bap, uint16_t *qmant, int n)
``` |
||

1157 | b6a1e523 | Justin Ruggles | { |

1158 | ```
int i;
``` |
||

1159 | |||

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

1161 | ```
int v;
``` |
||

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

1163 | 27af78cf | Justin Ruggles | ```
int e = exp[i] - exp_shift;
``` |

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

1165 | ```
switch (b) {
``` |
||

1166 | case 0: |
||

1167 | ```
v = 0;
``` |
||

1168 | ```
break;
``` |
||

1169 | case 1: |
||

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

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

1172 | case 0: |
||

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

1174 | ```
v = 9 * v;
``` |
||

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

1176 | ```
break;
``` |
||

1177 | case 1: |
||

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

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

1180 | ```
v = 128;
``` |
||

1181 | ```
break;
``` |
||

1182 | ```
default:
``` |
||

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

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

1185 | ```
v = 128;
``` |
||

1186 | ```
break;
``` |
||

1187 | } |
||

1188 | ```
break;
``` |
||

1189 | case 2: |
||

1190 | ```
v = sym_quant(c, e, 5);
``` |
||

1191 | ```
switch (s->mant2_cnt) {
``` |
||

1192 | case 0: |
||

1193 | s->qmant2_ptr = &qmant[i]; |
||

1194 | ```
v = 25 * v;
``` |
||

1195 | ```
s->mant2_cnt = 1;
``` |
||

1196 | ```
break;
``` |
||

1197 | case 1: |
||

1198 | ```
*s->qmant2_ptr += 5 * v;
``` |
||

1199 | ```
s->mant2_cnt = 2;
``` |
||

1200 | ```
v = 128;
``` |
||

1201 | ```
break;
``` |
||

1202 | ```
default:
``` |
||

1203 | *s->qmant2_ptr += v; |
||

1204 | ```
s->mant2_cnt = 0;
``` |
||

1205 | ```
v = 128;
``` |
||

1206 | ```
break;
``` |
||

1207 | } |
||

1208 | ```
break;
``` |
||

1209 | case 3: |
||

1210 | ```
v = sym_quant(c, e, 7);
``` |
||

1211 | ```
break;
``` |
||

1212 | case 4: |
||

1213 | ```
v = sym_quant(c, e, 11);
``` |
||

1214 | ```
switch (s->mant4_cnt) {
``` |
||

1215 | case 0: |
||

1216 | s->qmant4_ptr = &qmant[i]; |
||

1217 | ```
v = 11 * v;
``` |
||

1218 | ```
s->mant4_cnt = 1;
``` |
||

1219 | ```
break;
``` |
||

1220 | ```
default:
``` |
||

1221 | *s->qmant4_ptr += v; |
||

1222 | ```
s->mant4_cnt = 0;
``` |
||

1223 | ```
v = 128;
``` |
||

1224 | ```
break;
``` |
||

1225 | } |
||

1226 | ```
break;
``` |
||

1227 | case 5: |
||

1228 | ```
v = sym_quant(c, e, 15);
``` |
||

1229 | ```
break;
``` |
||

1230 | case 14: |
||

1231 | ```
v = asym_quant(c, e, 14);
``` |
||

1232 | ```
break;
``` |
||

1233 | case 15: |
||

1234 | ```
v = asym_quant(c, e, 16);
``` |
||

1235 | ```
break;
``` |
||

1236 | ```
default:
``` |
||

1237 | ```
v = asym_quant(c, e, b - 1);
``` |
||

1238 | ```
break;
``` |
||

1239 | } |
||

1240 | qmant[i] = v; |
||

1241 | } |
||

1242 | } |
||

1243 | |||

1244 | |||

1245 | ```
/**
``` |
||

1246 | ```
* Quantize mantissas using coefficients, exponents, and bit allocation pointers.
``` |
||

1247 | ```
*/
``` |
||

1248 | 266d24be | Justin Ruggles | static void quantize_mantissas(AC3EncodeContext *s) |

1249 | b6a1e523 | Justin Ruggles | { |

1250 | ```
int blk, ch;
``` |
||

1251 | |||

1252 | |||

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

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

1255 | b6a1e523 | Justin Ruggles | ```
s->mant1_cnt = s->mant2_cnt = s->mant4_cnt = 0;
``` |

1256 | ```
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL;
``` |
||

1257 | |||

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

1259 | ac05f903 | Justin Ruggles | quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch], |

1260 | 27af78cf | Justin Ruggles | block->exp[ch], block->bap[ch], |

1261 | 5901cebe | Justin Ruggles | block->qmant[ch], s->nb_coefs[ch]); |

1262 | b6a1e523 | Justin Ruggles | } |

1263 | } |
||

1264 | } |
||

1265 | |||

1266 | |||

1267 | ```
/**
``` |
||

1268 | 5b44ede0 | Justin Ruggles | ```
* Write the AC-3 frame header to the output bitstream.
``` |

1269 | ```
*/
``` |
||

1270 | static void output_frame_header(AC3EncodeContext *s) |
||

1271 | { |
||

1272 | put_bits(&s->pb, 16, 0x0b77); /* frame header */ |
||

1273 | put_bits(&s->pb, 16, 0); /* crc1: will be filled later */ |
||

1274 | ```
put_bits(&s->pb, 2, s->bit_alloc.sr_code);
``` |
||

1275 | put_bits(&s->pb, 6, s->frame_size_code + (s->frame_size - s->frame_size_min) / 2); |
||

1276 | ```
put_bits(&s->pb, 5, s->bitstream_id);
``` |
||

1277 | ```
put_bits(&s->pb, 3, s->bitstream_mode);
``` |
||

1278 | ```
put_bits(&s->pb, 3, s->channel_mode);
``` |
||

1279 | if ((s->channel_mode & 0x01) && s->channel_mode != AC3_CHMODE_MONO) |
||

1280 | put_bits(&s->pb, 2, 1); /* XXX -4.5 dB */ |
||

1281 | if (s->channel_mode & 0x04) |
||

1282 | put_bits(&s->pb, 2, 1); /* XXX -6 dB */ |
||

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

1284 | put_bits(&s->pb, 2, 0); /* surround not indicated */ |
||

1285 | put_bits(&s->pb, 1, s->lfe_on); /* LFE */ |
||

1286 | put_bits(&s->pb, 5, 31); /* dialog norm: -31 db */ |
||

1287 | put_bits(&s->pb, 1, 0); /* no compression control word */ |
||

1288 | put_bits(&s->pb, 1, 0); /* no lang code */ |
||

1289 | put_bits(&s->pb, 1, 0); /* no audio production info */ |
||

1290 | put_bits(&s->pb, 1, 0); /* no copyright */ |
||

1291 | put_bits(&s->pb, 1, 1); /* original bitstream */ |
||

1292 | put_bits(&s->pb, 1, 0); /* no time code 1 */ |
||

1293 | put_bits(&s->pb, 1, 0); /* no time code 2 */ |
||

1294 | put_bits(&s->pb, 1, 0); /* no additional bit stream info */ |
||

1295 | } |
||

1296 | |||

1297 | |||

1298 | ```
/**
``` |
||

1299 | c36ce0f8 | Justin Ruggles | ```
* Write one audio block to the output bitstream.
``` |

1300 | ```
*/
``` |
||

1301 | 5fc2e007 | Justin Ruggles | static void output_audio_block(AC3EncodeContext *s, int blk) |

1302 | de6d9b64 | Fabrice Bellard | { |

1303 | f94bacc5 | Justin Ruggles | ```
int ch, i, baie, rbnd;
``` |

1304 | 5fc2e007 | Justin Ruggles | AC3Block *block = &s->blocks[blk]; |

1305 | de6d9b64 | Fabrice Bellard | |

1306 | 2d82d9b1 | Justin Ruggles | ```
/* block switching */
``` |

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

1308 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 1, 0); |

1309 | |||

1310 | ```
/* dither flags */
``` |
||

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

1312 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 1, 1); |

1313 | |||

1314 | ```
/* dynamic range codes */
``` |
||

1315 | put_bits(&s->pb, 1, 0); |
||

1316 | |||

1317 | ```
/* channel coupling */
``` |
||

1318 | 5fc2e007 | Justin Ruggles | ```
if (!blk) {
``` |

1319 | de6d9b64 | Fabrice Bellard | put_bits(&s->pb, 1, 1); /* coupling strategy present */ |

1320 | put_bits(&s->pb, 1, 0); /* no coupling strategy */ |
||

1321 | ```
} else {
``` |
||

1322 | put_bits(&s->pb, 1, 0); /* no new coupling strategy */ |
||

1323 | } |
||

1324 | |||

1325 | 2d82d9b1 | Justin Ruggles | ```
/* stereo rematrixing */
``` |

1326 | 6a988808 | Justin Ruggles | ```
if (s->channel_mode == AC3_CHMODE_STEREO) {
``` |

1327 | dc7e07ac | Justin Ruggles | ```
put_bits(&s->pb, 1, block->new_rematrixing_strategy);
``` |

1328 | ```
if (block->new_rematrixing_strategy) {
``` |
||

1329 | ```
/* rematrixing flags */
``` |
||

1330 | 6a988808 | Justin Ruggles | for (rbnd = 0; rbnd < 4; rbnd++) |

1331 | dc7e07ac | Justin Ruggles | ```
put_bits(&s->pb, 1, block->rematrixing_flags[rbnd]);
``` |

1332 | 6a988808 | Justin Ruggles | } |

1333 | } |
||

1334 | de6d9b64 | Fabrice Bellard | |

1335 | ```
/* exponent strategy */
``` |
||

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

1337 | 5fc2e007 | Justin Ruggles | ```
put_bits(&s->pb, 2, s->exp_strategy[ch][blk]);
``` |

1338 | 6a988808 | Justin Ruggles | ```
if (s->lfe_on)
``` |

1339 | 5fc2e007 | Justin Ruggles | ```
put_bits(&s->pb, 1, s->exp_strategy[s->lfe_channel][blk]);
``` |

1340 | 30b68f33 | Zdenek Kabelac | |

1341 | 6a988808 | Justin Ruggles | ```
/* bandwidth */
``` |

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

1343 | 5fc2e007 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] != EXP_REUSE)
``` |

1344 | 2d2692eb | Justin Ruggles | ```
put_bits(&s->pb, 6, s->bandwidth_code[ch]);
``` |

1345 | de6d9b64 | Fabrice Bellard | } |

1346 | 115329f1 | Diego Biurrun | |

1347 | de6d9b64 | Fabrice Bellard | ```
/* exponents */
``` |

1348 | 2d2692eb | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

1349 | e86ea34d | Justin Ruggles | ```
int nb_groups;
``` |

1350 | |||

1351 | 5fc2e007 | Justin Ruggles | ```
if (s->exp_strategy[ch][blk] == EXP_REUSE)
``` |

1352 | de6d9b64 | Fabrice Bellard | ```
continue;
``` |

1353 | |||

1354 | 2d82d9b1 | Justin Ruggles | ```
/* DC exponent */
``` |

1355 | 5901cebe | Justin Ruggles | put_bits(&s->pb, 4, block->grouped_exp[ch][0]); |

1356 | f94bacc5 | Justin Ruggles | |

1357 | 2d82d9b1 | Justin Ruggles | ```
/* exponent groups */
``` |

1358 | 5fc2e007 | Justin Ruggles | ```
nb_groups = exponent_group_tab[s->exp_strategy[ch][blk]-1][s->nb_coefs[ch]];
``` |

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

1360 | 5901cebe | Justin Ruggles | ```
put_bits(&s->pb, 7, block->grouped_exp[ch][i]);
``` |

1361 | de6d9b64 | Fabrice Bellard | |

1362 | 2d82d9b1 | Justin Ruggles | ```
/* gain range info */
``` |

1363 | bb270c08 | Diego Biurrun | ```
if (ch != s->lfe_channel)
``` |

1364 | 2d82d9b1 | Justin Ruggles | put_bits(&s->pb, 2, 0); |

1365 | de6d9b64 | Fabrice Bellard | } |

1366 | |||

1367 | ```
/* bit allocation info */
``` |
||

1368 | 5fc2e007 | Justin Ruggles | ```
baie = (blk == 0);
``` |

1369 | de6d9b64 | Fabrice Bellard | ```
put_bits(&s->pb, 1, baie);
``` |

1370 | ```
if (baie) {
``` |
||

1371 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 2, s->slow_decay_code);
``` |

1372 | ```
put_bits(&s->pb, 2, s->fast_decay_code);
``` |
||

1373 | ```
put_bits(&s->pb, 2, s->slow_gain_code);
``` |
||

1374 | ```
put_bits(&s->pb, 2, s->db_per_bit_code);
``` |
||

1375 | ```
put_bits(&s->pb, 3, s->floor_code);
``` |
||

1376 | de6d9b64 | Fabrice Bellard | } |

1377 | |||

1378 | ```
/* snr offset */
``` |
||

1379 | 6a988808 | Justin Ruggles | ```
put_bits(&s->pb, 1, baie);
``` |

1380 | de6d9b64 | Fabrice Bellard | ```
if (baie) {
``` |

1381 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 6, s->coarse_snr_offset);
``` |

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

1383 | 5ce21342 | Justin Ruggles | ```
put_bits(&s->pb, 4, s->fine_snr_offset[ch]);
``` |

1384 | ```
put_bits(&s->pb, 3, s->fast_gain_code[ch]);
``` |
||

1385 | de6d9b64 | Fabrice Bellard | } |

1386 | } |
||

1387 | 115329f1 | Diego Biurrun | |

1388 | de6d9b64 | Fabrice Bellard | put_bits(&s->pb, 1, 0); /* no delta bit allocation */ |

1389 | put_bits(&s->pb, 1, 0); /* no data to skip */ |
||

1390 | |||

1391 | 2d82d9b1 | Justin Ruggles | ```
/* mantissas */
``` |

1392 | 2d2692eb | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) { |

1393 | de6d9b64 | Fabrice Bellard | ```
int b, q;
``` |

1394 | 6a988808 | Justin Ruggles | for (i = 0; i < s->nb_coefs[ch]; i++) { |

1395 | 5901cebe | Justin Ruggles | q = block->qmant[ch][i]; |

1396 | 171bc51c | Justin Ruggles | b = block->bap[ch][i]; |

1397 | 6a988808 | Justin Ruggles | ```
switch (b) {
``` |

1398 | case 0: break; |
||

1399 | case 1: if (q != 128) put_bits(&s->pb, 5, q); break; |
||

1400 | case 2: if (q != 128) put_bits(&s->pb, 7, q); break; |
||

1401 | case 3: put_bits(&s->pb, 3, q); break; |
||

1402 | case 4: if (q != 128) put_bits(&s->pb, 7, q); break; |
||

1403 | case 14: put_bits(&s->pb, 14, q); break; |
||

1404 | case 15: put_bits(&s->pb, 16, q); break; |
||

1405 | default: put_bits(&s->pb, b-1, q); break; |
||

1406 | de6d9b64 | Fabrice Bellard | } |

1407 | } |
||

1408 | } |
||

1409 | } |
||

1410 | |||

1411 | 2f8ae522 | Justin Ruggles | |

1412 | c36ce0f8 | Justin Ruggles | ```
/** CRC-16 Polynomial */
``` |

1413 | de6d9b64 | Fabrice Bellard | #define CRC16_POLY ((1 << 0) | (1 << 2) | (1 << 15) | (1 << 16)) |

1414 | |||

1415 | 2f8ae522 | Justin Ruggles | |

1416 | de6d9b64 | Fabrice Bellard | static unsigned int mul_poly(unsigned int a, unsigned int b, unsigned int poly) |

1417 | { |
||

1418 | unsigned int c; |
||

1419 | |||

1420 | ```
c = 0;
``` |
||

1421 | ```
while (a) {
``` |
||

1422 | if (a & 1) |
||

1423 | c ^= b; |
||

1424 | ```
a = a >> 1;
``` |
||

1425 | ```
b = b << 1;
``` |
||

1426 | if (b & (1 << 16)) |
||

1427 | b ^= poly; |
||

1428 | } |
||

1429 | ```
return c;
``` |
||

1430 | } |
||

1431 | |||

1432 | 2f8ae522 | Justin Ruggles | |

1433 | de6d9b64 | Fabrice Bellard | static unsigned int pow_poly(unsigned int a, unsigned int n, unsigned int poly) |

1434 | { |
||

1435 | unsigned int r; |
||

1436 | ```
r = 1;
``` |
||

1437 | ```
while (n) {
``` |
||

1438 | if (n & 1) |
||

1439 | r = mul_poly(r, a, poly); |
||

1440 | a = mul_poly(a, a, poly); |
||

1441 | ```
n >>= 1;
``` |
||

1442 | } |
||

1443 | ```
return r;
``` |
||

1444 | } |
||

1445 | |||

1446 | 2f8ae522 | Justin Ruggles | |

1447 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1448 | ```
* Fill the end of the frame with 0's and compute the two CRCs.
``` |
||

1449 | ```
*/
``` |
||

1450 | 1971ab6e | Justin Ruggles | static void output_frame_end(AC3EncodeContext *s) |

1451 | de6d9b64 | Fabrice Bellard | { |

1452 | a897423b | Justin Ruggles | ```
const AVCRC *crc_ctx = av_crc_get_table(AV_CRC_16_ANSI);
``` |

1453 | e96dc767 | Justin Ruggles | ```
int frame_size_58, pad_bytes, crc1, crc2_partial, crc2, crc_inv;
``` |

1454 | 0c1a9eda | Zdenek Kabelac | uint8_t *frame; |

1455 | de6d9b64 | Fabrice Bellard | |

1456 | 0e9b0643 | Justin Ruggles | frame_size_58 = ((s->frame_size >> 2) + (s->frame_size >> 4)) << 1; |

1457 | 2d82d9b1 | Justin Ruggles | |

1458 | ```
/* pad the remainder of the frame with zeros */
``` |
||

1459 | de6d9b64 | Fabrice Bellard | flush_put_bits(&s->pb); |

1460 | frame = s->pb.buf; |
||

1461 | 427e2293 | Justin Ruggles | ```
pad_bytes = s->frame_size - (put_bits_ptr(&s->pb) - frame) - 2;
``` |

1462 | eed00252 | Justin Ruggles | ```
assert(pad_bytes >= 0);
``` |

1463 | if (pad_bytes > 0) |
||

1464 | ```
memset(put_bits_ptr(&s->pb), 0, pad_bytes);
``` |
||

1465 | 115329f1 | Diego Biurrun | |

1466 | 2d82d9b1 | Justin Ruggles | ```
/* compute crc1 */
``` |

1467 | ```
/* this is not so easy because it is at the beginning of the data... */
``` |
||

1468 | b51c740e | Justin Ruggles | crc1 = av_bswap16(av_crc(crc_ctx, 0, frame + 4, frame_size_58 - 4)); |

1469 | a81d7c6a | Justin Ruggles | crc_inv = s->crc_inv[s->frame_size > s->frame_size_min]; |

1470 | 6a988808 | Justin Ruggles | crc1 = mul_poly(crc_inv, crc1, CRC16_POLY); |

1471 | ```
AV_WB16(frame + 2, crc1);
``` |
||

1472 | 115329f1 | Diego Biurrun | |

1473 | 2d82d9b1 | Justin Ruggles | ```
/* compute crc2 */
``` |

1474 | e96dc767 | Justin Ruggles | ```
crc2_partial = av_crc(crc_ctx, 0, frame + frame_size_58,
``` |

1475 | ```
s->frame_size - frame_size_58 - 3);
``` |
||

1476 | crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); |
||

1477 | ```
/* ensure crc2 does not match sync word by flipping crcrsv bit if needed */
``` |
||

1478 | if (crc2 == 0x770B) { |
||

1479 | frame[s->frame_size - 3] ^= 0x1; |
||

1480 | crc2 = av_crc(crc_ctx, crc2_partial, frame + s->frame_size - 3, 1); |
||

1481 | } |
||

1482 | crc2 = av_bswap16(crc2); |
||

1483 | 0e9b0643 | Justin Ruggles | ```
AV_WB16(frame + s->frame_size - 2, crc2);
``` |

1484 | de6d9b64 | Fabrice Bellard | } |

1485 | |||

1486 | 2f8ae522 | Justin Ruggles | |

1487 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1488 | 67d979fe | Justin Ruggles | ```
* Write the frame to the output bitstream.
``` |

1489 | ```
*/
``` |
||

1490 | b5293036 | Justin Ruggles | static void output_frame(AC3EncodeContext *s, unsigned char *frame) |

1491 | 67d979fe | Justin Ruggles | { |

1492 | ```
int blk;
``` |
||

1493 | |||

1494 | init_put_bits(&s->pb, frame, AC3_MAX_CODED_FRAME_SIZE); |
||

1495 | |||

1496 | output_frame_header(s); |
||

1497 | |||

1498 | 2d82d9b1 | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) |

1499 | 266d24be | Justin Ruggles | output_audio_block(s, blk); |

1500 | 67d979fe | Justin Ruggles | |

1501 | output_frame_end(s); |
||

1502 | } |
||

1503 | |||

1504 | |||

1505 | ```
/**
``` |
||

1506 | c36ce0f8 | Justin Ruggles | ```
* Encode a single AC-3 frame.
``` |

1507 | ```
*/
``` |
||

1508 | b5293036 | Justin Ruggles | static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, |

1509 | int buf_size, void *data) |
||

1510 | de6d9b64 | Fabrice Bellard | { |

1511 | AC3EncodeContext *s = avctx->priv_data; |
||

1512 | 0cbd5ff7 | Justin Ruggles | ```
const SampleType *samples = data;
``` |

1513 | dc0bc0f8 | Justin Ruggles | ```
int ret;
``` |

1514 | de6d9b64 | Fabrice Bellard | |

1515 | 160d85f5 | Justin Ruggles | if (s->bit_alloc.sr_code == 1) |

1516 | adjust_frame_size(s); |
||

1517 | |||

1518 | 266d24be | Justin Ruggles | deinterleave_input_samples(s, samples); |

1519 | 12ed6226 | Justin Ruggles | |

1520 | 266d24be | Justin Ruggles | apply_mdct(s); |

1521 | 115329f1 | Diego Biurrun | |

1522 | dc7e07ac | Justin Ruggles | compute_rematrixing_strategy(s); |

1523 | |||

1524 | ac05f903 | Justin Ruggles | scale_coefficients(s); |

1525 | |||

1526 | dc7e07ac | Justin Ruggles | apply_rematrixing(s); |

1527 | |||

1528 | 266d24be | Justin Ruggles | process_exponents(s); |

1529 | de6d9b64 | Fabrice Bellard | |

1530 | 266d24be | Justin Ruggles | ret = compute_bit_allocation(s); |

1531 | dc0bc0f8 | Justin Ruggles | ```
if (ret) {
``` |

1532 | ```
av_log(avctx, AV_LOG_ERROR, "Bit allocation failed. Try increasing the bitrate.\n");
``` |
||

1533 | ```
return ret;
``` |
||

1534 | } |
||

1535 | 084f5c5a | Justin Ruggles | |

1536 | 266d24be | Justin Ruggles | quantize_mantissas(s); |

1537 | b6a1e523 | Justin Ruggles | |

1538 | 266d24be | Justin Ruggles | output_frame(s, frame); |

1539 | 1971ab6e | Justin Ruggles | |

1540 | 427e2293 | Justin Ruggles | ```
return s->frame_size;
``` |

1541 | de6d9b64 | Fabrice Bellard | } |

1542 | |||

1543 | 2f8ae522 | Justin Ruggles | |

1544 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1545 | ```
* Finalize encoding and free any memory allocated by the encoder.
``` |
||

1546 | ```
*/
``` |
||

1547 | a0a9204e | Justin Ruggles | static av_cold int ac3_encode_close(AVCodecContext *avctx) |

1548 | 492cd3a9 | Michael Niedermayer | { |

1549 | e8d21fba | Justin Ruggles | ```
int blk, ch;
``` |

1550 | 171bc51c | Justin Ruggles | AC3EncodeContext *s = avctx->priv_data; |

1551 | |||

1552 | e8d21fba | Justin Ruggles | for (ch = 0; ch < s->channels; ch++) |

1553 | av_freep(&s->planar_samples[ch]); |
||

1554 | av_freep(&s->planar_samples); |
||

1555 | 171bc51c | Justin Ruggles | av_freep(&s->bap_buffer); |

1556 | av_freep(&s->bap1_buffer); |
||

1557 | b6f6204d | Justin Ruggles | av_freep(&s->mdct_coef_buffer); |

1558 | ac05f903 | Justin Ruggles | av_freep(&s->fixed_coef_buffer); |

1559 | b6f6204d | Justin Ruggles | av_freep(&s->exp_buffer); |

1560 | av_freep(&s->grouped_exp_buffer); |
||

1561 | av_freep(&s->psd_buffer); |
||

1562 | av_freep(&s->band_psd_buffer); |
||

1563 | av_freep(&s->mask_buffer); |
||

1564 | av_freep(&s->qmant_buffer); |
||

1565 | 171bc51c | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

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

1567 | av_freep(&block->bap); |
||

1568 | b6f6204d | Justin Ruggles | av_freep(&block->mdct_coef); |

1569 | ac05f903 | Justin Ruggles | av_freep(&block->fixed_coef); |

1570 | b6f6204d | Justin Ruggles | av_freep(&block->exp); |

1571 | av_freep(&block->grouped_exp); |
||

1572 | av_freep(&block->psd); |
||

1573 | av_freep(&block->band_psd); |
||

1574 | av_freep(&block->mask); |
||

1575 | av_freep(&block->qmant); |
||

1576 | 171bc51c | Justin Ruggles | } |

1577 | |||

1578 | c41ac4f8 | Justin Ruggles | mdct_end(&s->mdct); |

1579 | |||

1580 | 492cd3a9 | Michael Niedermayer | av_freep(&avctx->coded_frame); |

1581 | ef9f7306 | MÃ¥ns RullgÃ¥rd | return 0; |

1582 | 492cd3a9 | Michael Niedermayer | } |

1583 | |||

1584 | 2f8ae522 | Justin Ruggles | |

1585 | c36ce0f8 | Justin Ruggles | ```
/**
``` |

1586 | ```
* Set channel information during initialization.
``` |
||

1587 | ```
*/
``` |
||

1588 | e77fd066 | Justin Ruggles | static av_cold int set_channel_info(AC3EncodeContext *s, int channels, |

1589 | int64_t *channel_layout) |
||

1590 | { |
||

1591 | ```
int ch_layout;
``` |
||

1592 | |||

1593 | if (channels < 1 || channels > AC3_MAX_CHANNELS) |
||

1594 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1595 | e77fd066 | Justin Ruggles | if ((uint64_t)*channel_layout > 0x7FF) |

1596 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1597 | e77fd066 | Justin Ruggles | ch_layout = *channel_layout; |

1598 | ```
if (!ch_layout)
``` |
||

1599 | ```
ch_layout = avcodec_guess_channel_layout(channels, CODEC_ID_AC3, NULL);
``` |
||

1600 | ```
if (av_get_channel_layout_nb_channels(ch_layout) != channels)
``` |
||

1601 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1602 | e77fd066 | Justin Ruggles | |

1603 | s->lfe_on = !!(ch_layout & AV_CH_LOW_FREQUENCY); |
||

1604 | s->channels = channels; |
||

1605 | s->fbw_channels = channels - s->lfe_on; |
||

1606 | ```
s->lfe_channel = s->lfe_on ? s->fbw_channels : -1;
``` |
||

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

1608 | ch_layout -= AV_CH_LOW_FREQUENCY; |
||

1609 | |||

1610 | ```
switch (ch_layout) {
``` |
||

1611 | case AV_CH_LAYOUT_MONO: s->channel_mode = AC3_CHMODE_MONO; break; |
||

1612 | case AV_CH_LAYOUT_STEREO: s->channel_mode = AC3_CHMODE_STEREO; break; |
||

1613 | case AV_CH_LAYOUT_SURROUND: s->channel_mode = AC3_CHMODE_3F; break; |
||

1614 | case AV_CH_LAYOUT_2_1: s->channel_mode = AC3_CHMODE_2F1R; break; |
||

1615 | case AV_CH_LAYOUT_4POINT0: s->channel_mode = AC3_CHMODE_3F1R; break; |
||

1616 | ```
case AV_CH_LAYOUT_QUAD:
``` |
||

1617 | case AV_CH_LAYOUT_2_2: s->channel_mode = AC3_CHMODE_2F2R; break; |
||

1618 | ```
case AV_CH_LAYOUT_5POINT0:
``` |
||

1619 | case AV_CH_LAYOUT_5POINT0_BACK: s->channel_mode = AC3_CHMODE_3F2R; break; |
||

1620 | ```
default:
``` |
||

1621 | ddf63d37 | Justin Ruggles | ```
return AVERROR(EINVAL);
``` |

1622 | e77fd066 | Justin Ruggles | } |

1623 | |||

1624 | s->channel_map = ff_ac3_enc_channel_map[s->channel_mode][s->lfe_on]; |
||

1625 | *channel_layout = ch_layout; |
||

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

1627 | *channel_layout |= AV_CH_LOW_FREQUENCY; |
||

1628 | |||

1629 | return 0; |
||

1630 | } |
||

1631 | |||

1632 | 2f8ae522 | Justin Ruggles | |

1633 | 8f60f70d | Justin Ruggles | static av_cold int validate_options(AVCodecContext *avctx, AC3EncodeContext *s) |

1634 | e77fd066 | Justin Ruggles | { |

1635 | ddf63d37 | Justin Ruggles | ```
int i, ret;
``` |

1636 | e77fd066 | Justin Ruggles | |

1637 | e0685bc9 | Justin Ruggles | ```
/* validate channel layout */
``` |

1638 | e77fd066 | Justin Ruggles | ```
if (!avctx->channel_layout) {
``` |

1639 | ```
av_log(avctx, AV_LOG_WARNING, "No channel layout specified. The "
``` |
||

1640 | ```
"encoder will guess the layout, but it "
``` |
||

1641 | ```
"might be incorrect.\n");
``` |
||

1642 | } |
||

1643 | ddf63d37 | Justin Ruggles | ret = set_channel_info(s, avctx->channels, &avctx->channel_layout); |

1644 | ```
if (ret) {
``` |
||

1645 | e77fd066 | Justin Ruggles | ```
av_log(avctx, AV_LOG_ERROR, "invalid channel layout\n");
``` |

1646 | ddf63d37 | Justin Ruggles | ```
return ret;
``` |

1647 | e77fd066 | Justin Ruggles | } |

1648 | |||

1649 | e0685bc9 | Justin Ruggles | ```
/* validate sample rate */
``` |

1650 | 99ca4f73 | Justin Ruggles | for (i = 0; i < 9; i++) { |

1651 | if ((ff_ac3_sample_rate_tab[i / 3] >> (i % 3)) == avctx->sample_rate) |
||

1652 | ```
break;
``` |
||

1653 | e77fd066 | Justin Ruggles | } |

1654 | 99ca4f73 | Justin Ruggles | if (i == 9) { |

1655 | ddf63d37 | Justin Ruggles | ```
av_log(avctx, AV_LOG_ERROR, "invalid sample rate\n");
``` |

1656 | ```
return AVERROR(EINVAL);
``` |
||

1657 | 99ca4f73 | Justin Ruggles | } |

1658 | 1607db0a | Justin Ruggles | s->sample_rate = avctx->sample_rate; |

1659 | 99ca4f73 | Justin Ruggles | ```
s->bit_alloc.sr_shift = i % 3;
``` |

1660 | ```
s->bit_alloc.sr_code = i / 3;
``` |
||

1661 | e77fd066 | Justin Ruggles | |

1662 | e0685bc9 | Justin Ruggles | ```
/* validate bit rate */
``` |

1663 | e77fd066 | Justin Ruggles | for (i = 0; i < 19; i++) { |

1664 | 1607db0a | Justin Ruggles | if ((ff_ac3_bitrate_tab[i] >> s->bit_alloc.sr_shift)*1000 == avctx->bit_rate) |

1665 | e77fd066 | Justin Ruggles | ```
break;
``` |

1666 | } |
||

1667 | ddf63d37 | Justin Ruggles | if (i == 19) { |

1668 | ```
av_log(avctx, AV_LOG_ERROR, "invalid bit rate\n");
``` |
||

1669 | ```
return AVERROR(EINVAL);
``` |
||

1670 | } |
||

1671 | 1607db0a | Justin Ruggles | s->bit_rate = avctx->bit_rate; |

1672 | e77fd066 | Justin Ruggles | ```
s->frame_size_code = i << 1;
``` |

1673 | 8f60f70d | Justin Ruggles | |

1674 | e62ef8f2 | Justin Ruggles | ```
/* validate cutoff */
``` |

1675 | if (avctx->cutoff < 0) { |
||

1676 | ```
av_log(avctx, AV_LOG_ERROR, "invalid cutoff frequency\n");
``` |
||

1677 | ```
return AVERROR(EINVAL);
``` |
||

1678 | } |
||

1679 | s->cutoff = avctx->cutoff; |
||

1680 | if (s->cutoff > (s->sample_rate >> 1)) |
||

1681 | ```
s->cutoff = s->sample_rate >> 1;
``` |
||

1682 | |||

1683 | 8f60f70d | Justin Ruggles | return 0; |

1684 | } |
||

1685 | |||

1686 | |||

1687 | ```
/**
``` |
||

1688 | 282255bb | Justin Ruggles | ```
* Set bandwidth for all channels.
``` |

1689 | ```
* The user can optionally supply a cutoff frequency. Otherwise an appropriate
``` |
||

1690 | ```
* default value will be used.
``` |
||

1691 | ```
*/
``` |
||

1692 | e62ef8f2 | Justin Ruggles | static av_cold void set_bandwidth(AC3EncodeContext *s) |

1693 | 282255bb | Justin Ruggles | { |

1694 | ```
int ch, bw_code;
``` |
||

1695 | |||

1696 | e62ef8f2 | Justin Ruggles | ```
if (s->cutoff) {
``` |

1697 | 282255bb | Justin Ruggles | ```
/* calculate bandwidth based on user-specified cutoff frequency */
``` |

1698 | ```
int fbw_coeffs;
``` |
||

1699 | e62ef8f2 | Justin Ruggles | ```
fbw_coeffs = s->cutoff * 2 * AC3_MAX_COEFS / s->sample_rate;
``` |

1700 | 282255bb | Justin Ruggles | bw_code = av_clip((fbw_coeffs - 73) / 3, 0, 60); |

1701 | ```
} else {
``` |
||

1702 | ```
/* use default bandwidth setting */
``` |
||

1703 | ```
/* XXX: should compute the bandwidth according to the frame
``` |
||

1704 | ```
size, so that we avoid annoying high frequency artifacts */
``` |
||

1705 | ```
bw_code = 50;
``` |
||

1706 | } |
||

1707 | |||

1708 | ```
/* set number of coefficients for each channel */
``` |
||

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

1710 | s->bandwidth_code[ch] = bw_code; |
||

1711 | s->nb_coefs[ch] = bw_code * 3 + 73; |
||

1712 | } |
||

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

1714 | s->nb_coefs[s->lfe_channel] = 7; /* LFE channel always has 7 coefs */ |
||

1715 | } |
||

1716 | |||

1717 | |||

1718 | 171bc51c | Justin Ruggles | static av_cold int allocate_buffers(AVCodecContext *avctx) |

1719 | { |
||

1720 | e8d21fba | Justin Ruggles | ```
int blk, ch;
``` |

1721 | 171bc51c | Justin Ruggles | AC3EncodeContext *s = avctx->priv_data; |

1722 | |||

1723 | e8d21fba | Justin Ruggles | ```
FF_ALLOC_OR_GOTO(avctx, s->planar_samples, s->channels * sizeof(*s->planar_samples),
``` |

1724 | alloc_fail); |
||

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

1726 | FF_ALLOCZ_OR_GOTO(avctx, s->planar_samples[ch], |
||

1727 | ```
(AC3_FRAME_SIZE+AC3_BLOCK_SIZE) * sizeof(**s->planar_samples),
``` |
||

1728 | alloc_fail); |
||

1729 | } |
||

1730 | 171bc51c | Justin Ruggles | FF_ALLOC_OR_GOTO(avctx, s->bap_buffer, AC3_MAX_BLOCKS * s->channels * |

1731 | ```
AC3_MAX_COEFS * sizeof(*s->bap_buffer), alloc_fail);
``` |
||

1732 | FF_ALLOC_OR_GOTO(avctx, s->bap1_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1733 | ```
AC3_MAX_COEFS * sizeof(*s->bap1_buffer), alloc_fail);
``` |
||

1734 | b6f6204d | Justin Ruggles | FF_ALLOC_OR_GOTO(avctx, s->mdct_coef_buffer, AC3_MAX_BLOCKS * s->channels * |

1735 | ```
AC3_MAX_COEFS * sizeof(*s->mdct_coef_buffer), alloc_fail);
``` |
||

1736 | FF_ALLOC_OR_GOTO(avctx, s->exp_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1737 | ```
AC3_MAX_COEFS * sizeof(*s->exp_buffer), alloc_fail);
``` |
||

1738 | FF_ALLOC_OR_GOTO(avctx, s->grouped_exp_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1739 | 128 * sizeof(*s->grouped_exp_buffer), alloc_fail); |
||

1740 | FF_ALLOC_OR_GOTO(avctx, s->psd_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1741 | ```
AC3_MAX_COEFS * sizeof(*s->psd_buffer), alloc_fail);
``` |
||

1742 | FF_ALLOC_OR_GOTO(avctx, s->band_psd_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1743 | 64 * sizeof(*s->band_psd_buffer), alloc_fail); |
||

1744 | FF_ALLOC_OR_GOTO(avctx, s->mask_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1745 | 64 * sizeof(*s->mask_buffer), alloc_fail); |
||

1746 | FF_ALLOC_OR_GOTO(avctx, s->qmant_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1747 | ```
AC3_MAX_COEFS * sizeof(*s->qmant_buffer), alloc_fail);
``` |
||

1748 | 171bc51c | Justin Ruggles | for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) { |

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

1750 | ```
FF_ALLOC_OR_GOTO(avctx, block->bap, s->channels * sizeof(*block->bap),
``` |
||

1751 | alloc_fail); |
||

1752 | b6f6204d | Justin Ruggles | ```
FF_ALLOCZ_OR_GOTO(avctx, block->mdct_coef, s->channels * sizeof(*block->mdct_coef),
``` |

1753 | alloc_fail); |
||

1754 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->exp, s->channels * sizeof(*block->exp),
``` |
||

1755 | alloc_fail); |
||

1756 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->grouped_exp, s->channels * sizeof(*block->grouped_exp),
``` |
||

1757 | alloc_fail); |
||

1758 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->psd, s->channels * sizeof(*block->psd),
``` |
||

1759 | alloc_fail); |
||

1760 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->band_psd, s->channels * sizeof(*block->band_psd),
``` |
||

1761 | alloc_fail); |
||

1762 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->mask, s->channels * sizeof(*block->mask),
``` |
||

1763 | alloc_fail); |
||

1764 | ```
FF_ALLOCZ_OR_GOTO(avctx, block->qmant, s->channels * sizeof(*block->qmant),
``` |
||

1765 | alloc_fail); |
||

1766 | |||

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

1768 | 7cc4be58 | Justin Ruggles | ```
/* arrangement: block, channel, coeff */
``` |

1769 | b6f6204d | Justin Ruggles | block->bap[ch] = &s->bap_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |

1770 | block->mdct_coef[ch] = &s->mdct_coef_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1771 | ```
block->grouped_exp[ch] = &s->grouped_exp_buffer[128 * (blk * s->channels + ch)];
``` |
||

1772 | block->psd[ch] = &s->psd_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1773 | ```
block->band_psd[ch] = &s->band_psd_buffer [64 * (blk * s->channels + ch)];
``` |
||

1774 | ```
block->mask[ch] = &s->mask_buffer [64 * (blk * s->channels + ch)];
``` |
||

1775 | block->qmant[ch] = &s->qmant_buffer [AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1776 | 7cc4be58 | Justin Ruggles | |

1777 | ```
/* arrangement: channel, block, coeff */
``` |
||

1778 | block->exp[ch] = &s->exp_buffer [AC3_MAX_COEFS * (AC3_MAX_BLOCKS * ch + blk)]; |
||

1779 | b6f6204d | Justin Ruggles | } |

1780 | 171bc51c | Justin Ruggles | } |

1781 | |||

1782 | ac05f903 | Justin Ruggles | ```
if (CONFIG_AC3ENC_FLOAT) {
``` |

1783 | FF_ALLOC_OR_GOTO(avctx, s->fixed_coef_buffer, AC3_MAX_BLOCKS * s->channels * |
||

1784 | ```
AC3_MAX_COEFS * sizeof(*s->fixed_coef_buffer), alloc_fail);
``` |
||

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

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

1787 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * |
||

1788 | ```
sizeof(*block->fixed_coef), alloc_fail);
``` |
||

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

1790 | block->fixed_coef[ch] = &s->fixed_coef_buffer[AC3_MAX_COEFS * (blk * s->channels + ch)]; |
||

1791 | } |
||

1792 | ```
} else {
``` |
||

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

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

1795 | FF_ALLOCZ_OR_GOTO(avctx, block->fixed_coef, s->channels * |
||

1796 | ```
sizeof(*block->fixed_coef), alloc_fail);
``` |
||

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

1798 | block->fixed_coef[ch] = (int32_t *)block->mdct_coef[ch]; |
||

1799 | } |
||

1800 | } |
||

1801 | |||

1802 | 171bc51c | Justin Ruggles | return 0; |

1803 | ```
alloc_fail:
``` |
||

1804 | ```
return AVERROR(ENOMEM);
``` |
||

1805 | } |
||

1806 | |||

1807 | |||

1808 | 282255bb | Justin Ruggles | ```
/**
``` |

1809 | 8f60f70d | Justin Ruggles | ```
* Initialize the encoder.
``` |

1810 | ```
*/
``` |
||

1811 | static av_cold int ac3_encode_init(AVCodecContext *avctx) |
||

1812 | { |
||

1813 | AC3EncodeContext *s = avctx->priv_data; |
||

1814 | a81d7c6a | Justin Ruggles | ```
int ret, frame_size_58;
``` |

1815 | 8f60f70d | Justin Ruggles | |

1816 | avctx->frame_size = AC3_FRAME_SIZE; |
||

1817 | |||

1818 | ac3_common_init(); |
||

1819 | |||

1820 | ret = validate_options(avctx, s); |
||

1821 | ```
if (ret)
``` |
||

1822 | ```
return ret;
``` |
||

1823 | |||

1824 | e35c984a | Justin Ruggles | ```
s->bitstream_id = 8 + s->bit_alloc.sr_shift;
``` |

1825 | s->bitstream_mode = 0; /* complete main audio service */ |
||

1826 | |||

1827 | 427e2293 | Justin Ruggles | ```
s->frame_size_min = 2 * ff_ac3_frame_size_tab[s->frame_size_code][s->bit_alloc.sr_code];
``` |

1828 | e77fd066 | Justin Ruggles | ```
s->bits_written = 0;
``` |

1829 | ```
s->samples_written = 0;
``` |
||

1830 | s->frame_size = s->frame_size_min; |
||

1831 | |||

1832 | a81d7c6a | Justin Ruggles | ```
/* calculate crc_inv for both possible frame sizes */
``` |

1833 | frame_size_58 = (( s->frame_size >> 2) + ( s->frame_size >> 4)) << 1; |
||

1834 | s->crc_inv[0] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); |
||

1835 | if (s->bit_alloc.sr_code == 1) { |
||

1836 | frame_size_58 = (((s->frame_size+2) >> 2) + ((s->frame_size+2) >> 4)) << 1; |
||

1837 | s->crc_inv[1] = pow_poly((CRC16_POLY >> 1), (8 * frame_size_58) - 16, CRC16_POLY); |
||

1838 | } |
||

1839 | |||

1840 | e62ef8f2 | Justin Ruggles | set_bandwidth(s); |

1841 | e77fd066 | Justin Ruggles | |

1842 | dc7e07ac | Justin Ruggles | rematrixing_init(s); |

1843 | |||

1844 | e86ea34d | Justin Ruggles | exponent_init(s); |

1845 | |||

1846 | 793bbf95 | Justin Ruggles | bit_alloc_init(s); |

1847 | e77fd066 | Justin Ruggles | |

1848 | 14166a6d | Justin Ruggles | ```
ret = mdct_init(avctx, &s->mdct, 9);
``` |

1849 | 7786c384 | Justin Ruggles | ```
if (ret)
``` |

1850 | 89bedc4d | Justin Ruggles | ```
goto init_fail;
``` |

1851 | e77fd066 | Justin Ruggles | |

1852 | 171bc51c | Justin Ruggles | ret = allocate_buffers(avctx); |

1853 | 7786c384 | Justin Ruggles | ```
if (ret)
``` |

1854 | 89bedc4d | Justin Ruggles | ```
goto init_fail;
``` |

1855 | 171bc51c | Justin Ruggles | |

1856 | e77fd066 | Justin Ruggles | avctx->coded_frame= avcodec_alloc_frame(); |

1857 | |||

1858 | 8846ee54 | Justin Ruggles | dsputil_init(&s->dsp, avctx); |

1859 | |||

1860 | e77fd066 | Justin Ruggles | return 0; |

1861 | 89bedc4d | Justin Ruggles | ```
init_fail:
``` |

1862 | ac3_encode_close(avctx); |
||

1863 | ```
return ret;
``` |
||

1864 | e77fd066 | Justin Ruggles | } |