## ffmpeg / libavcodec / flacenc.c @ 94d85eaf

History | View | Annotate | Download (20.5 KB)

1 | 9e96ab03 | Michael Niedermayer | ```
/**
``` |
---|---|---|---|

2 | ```
* FLAC audio encoder
``` |
||

3 | ```
* Copyright (c) 2006 Justin Ruggles <jruggle@earthlink.net>
``` |
||

4 | ```
*
``` |
||

5 | ```
* This library is free software; you can redistribute it and/or
``` |
||

6 | ```
* modify it under the terms of the GNU Lesser General Public
``` |
||

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

8 | ```
* version 2 of the License, or (at your option) any later version.
``` |
||

9 | ```
*
``` |
||

10 | ```
* This library is distributed in the hope that it will be useful,
``` |
||

11 | ```
* but WITHOUT ANY WARRANTY; without even the implied warranty of
``` |
||

12 | ```
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
``` |
||

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

14 | ```
*
``` |
||

15 | ```
* You should have received a copy of the GNU Lesser General Public
``` |
||

16 | ```
* License along with this library; if not, write to the Free Software
``` |
||

17 | ```
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
``` |
||

18 | ```
*/
``` |
||

19 | |||

20 | #include "avcodec.h" |
||

21 | #include "bitstream.h" |
||

22 | #include "crc.h" |
||

23 | #include "golomb.h" |
||

24 | |||

25 | #define FLAC_MAX_CH 8 |
||

26 | #define FLAC_MIN_BLOCKSIZE 16 |
||

27 | #define FLAC_MAX_BLOCKSIZE 65535 |
||

28 | |||

29 | #define FLAC_SUBFRAME_CONSTANT 0 |
||

30 | #define FLAC_SUBFRAME_VERBATIM 1 |
||

31 | #define FLAC_SUBFRAME_FIXED 8 |
||

32 | #define FLAC_SUBFRAME_LPC 32 |
||

33 | |||

34 | #define FLAC_CHMODE_NOT_STEREO 0 |
||

35 | #define FLAC_CHMODE_LEFT_RIGHT 1 |
||

36 | #define FLAC_CHMODE_LEFT_SIDE 8 |
||

37 | #define FLAC_CHMODE_RIGHT_SIDE 9 |
||

38 | #define FLAC_CHMODE_MID_SIDE 10 |
||

39 | |||

40 | #define FLAC_STREAMINFO_SIZE 34 |
||

41 | |||

42 | e71bcc37 | Justin Ruggles | typedef struct RiceContext { |

43 | ```
int porder;
``` |
||

44 | int params[256]; |
||

45 | } RiceContext; |
||

46 | |||

47 | 9e96ab03 | Michael Niedermayer | typedef struct FlacSubframe { |

48 | ```
int type;
``` |
||

49 | ```
int type_code;
``` |
||

50 | ```
int obits;
``` |
||

51 | ```
int order;
``` |
||

52 | e71bcc37 | Justin Ruggles | RiceContext rc; |

53 | 9e96ab03 | Michael Niedermayer | int32_t samples[FLAC_MAX_BLOCKSIZE]; |

54 | int32_t residual[FLAC_MAX_BLOCKSIZE]; |
||

55 | } FlacSubframe; |
||

56 | |||

57 | typedef struct FlacFrame { |
||

58 | FlacSubframe subframes[FLAC_MAX_CH]; |
||

59 | ```
int blocksize;
``` |
||

60 | int bs_code[2]; |
||

61 | uint8_t crc8; |
||

62 | ```
int ch_mode;
``` |
||

63 | } FlacFrame; |
||

64 | |||

65 | typedef struct FlacEncodeContext { |
||

66 | PutBitContext pb; |
||

67 | ```
int channels;
``` |
||

68 | ```
int ch_code;
``` |
||

69 | ```
int samplerate;
``` |
||

70 | int sr_code[2]; |
||

71 | ```
int blocksize;
``` |
||

72 | ```
int max_framesize;
``` |
||

73 | uint32_t frame_count; |
||

74 | FlacFrame frame; |
||

75 | e71bcc37 | Justin Ruggles | AVCodecContext *avctx; |

76 | 9e96ab03 | Michael Niedermayer | } FlacEncodeContext; |

77 | |||

78 | static const int flac_samplerates[16] = { |
||

79 | 0, 0, 0, 0, |
||

80 | 8000, 16000, 22050, 24000, 32000, 44100, 48000, 96000, |
||

81 | 0, 0, 0, 0 |
||

82 | }; |
||

83 | |||

84 | static const int flac_blocksizes[16] = { |
||

85 | ```
0,
``` |
||

86 | ```
192,
``` |
||

87 | 576, 1152, 2304, 4608, |
||

88 | 0, 0, |
||

89 | 256, 512, 1024, 2048, 4096, 8192, 16384, 32768 |
||

90 | }; |
||

91 | |||

92 | ```
/**
``` |
||

93 | ```
* Writes streaminfo metadata block to byte array
``` |
||

94 | ```
*/
``` |
||

95 | static void write_streaminfo(FlacEncodeContext *s, uint8_t *header) |
||

96 | { |
||

97 | PutBitContext pb; |
||

98 | |||

99 | ```
memset(header, 0, FLAC_STREAMINFO_SIZE);
``` |
||

100 | init_put_bits(&pb, header, FLAC_STREAMINFO_SIZE); |
||

101 | |||

102 | ```
/* streaminfo metadata block */
``` |
||

103 | ```
put_bits(&pb, 16, s->blocksize);
``` |
||

104 | ```
put_bits(&pb, 16, s->blocksize);
``` |
||

105 | put_bits(&pb, 24, 0); |
||

106 | ```
put_bits(&pb, 24, s->max_framesize);
``` |
||

107 | ```
put_bits(&pb, 20, s->samplerate);
``` |
||

108 | put_bits(&pb, 3, s->channels-1); |
||

109 | put_bits(&pb, 5, 15); /* bits per sample - 1 */ |
||

110 | flush_put_bits(&pb); |
||

111 | ```
/* total samples = 0 */
``` |
||

112 | ```
/* MD5 signature = 0 */
``` |
||

113 | } |
||

114 | |||

115 | e71bcc37 | Justin Ruggles | #define BLOCK_TIME_MS 27 |

116 | 9e96ab03 | Michael Niedermayer | |

117 | ```
/**
``` |
||

118 | ```
* Sets blocksize based on samplerate
``` |
||

119 | ```
* Chooses the closest predefined blocksize >= BLOCK_TIME_MS milliseconds
``` |
||

120 | ```
*/
``` |
||

121 | static int select_blocksize(int samplerate) |
||

122 | { |
||

123 | ```
int i;
``` |
||

124 | ```
int target;
``` |
||

125 | ```
int blocksize;
``` |
||

126 | |||

127 | ```
assert(samplerate > 0);
``` |
||

128 | d1015e88 | Michael Niedermayer | ```
blocksize = flac_blocksizes[1];
``` |

129 | 9e96ab03 | Michael Niedermayer | ```
target = (samplerate * BLOCK_TIME_MS) / 1000;
``` |

130 | d1015e88 | Michael Niedermayer | for(i=0; i<16; i++) { |

131 | ```
if(target >= flac_blocksizes[i] && flac_blocksizes[i] > blocksize) {
``` |
||

132 | blocksize = flac_blocksizes[i]; |
||

133 | 9e96ab03 | Michael Niedermayer | } |

134 | } |
||

135 | ```
return blocksize;
``` |
||

136 | } |
||

137 | |||

138 | static int flac_encode_init(AVCodecContext *avctx) |
||

139 | { |
||

140 | ```
int freq = avctx->sample_rate;
``` |
||

141 | ```
int channels = avctx->channels;
``` |
||

142 | FlacEncodeContext *s = avctx->priv_data; |
||

143 | ```
int i;
``` |
||

144 | uint8_t *streaminfo; |
||

145 | |||

146 | e71bcc37 | Justin Ruggles | s->avctx = avctx; |

147 | |||

148 | 9e96ab03 | Michael Niedermayer | ```
if(avctx->sample_fmt != SAMPLE_FMT_S16) {
``` |

149 | return -1; |
||

150 | } |
||

151 | |||

152 | if(channels < 1 || channels > FLAC_MAX_CH) { |
||

153 | return -1; |
||

154 | } |
||

155 | s->channels = channels; |
||

156 | ```
s->ch_code = s->channels-1;
``` |
||

157 | |||

158 | ```
/* find samplerate in table */
``` |
||

159 | if(freq < 1) |
||

160 | return -1; |
||

161 | for(i=4; i<12; i++) { |
||

162 | ```
if(freq == flac_samplerates[i]) {
``` |
||

163 | s->samplerate = flac_samplerates[i]; |
||

164 | ```
s->sr_code[0] = i;
``` |
||

165 | s->sr_code[1] = 0; |
||

166 | ```
break;
``` |
||

167 | } |
||

168 | } |
||

169 | ```
/* if not in table, samplerate is non-standard */
``` |
||

170 | if(i == 12) { |
||

171 | if(freq % 1000 == 0 && freq < 255000) { |
||

172 | s->sr_code[0] = 12; |
||

173 | s->sr_code[1] = freq / 1000; |
||

174 | } else if(freq % 10 == 0 && freq < 655350) { |
||

175 | s->sr_code[0] = 14; |
||

176 | s->sr_code[1] = freq / 10; |
||

177 | } else if(freq < 65535) { |
||

178 | s->sr_code[0] = 13; |
||

179 | ```
s->sr_code[1] = freq;
``` |
||

180 | ```
} else {
``` |
||

181 | return -1; |
||

182 | } |
||

183 | s->samplerate = freq; |
||

184 | } |
||

185 | |||

186 | s->blocksize = select_blocksize(s->samplerate); |
||

187 | avctx->frame_size = s->blocksize; |
||

188 | |||

189 | f33aa120 | Michael Niedermayer | ```
/* set maximum encoded frame size in verbatim mode */
``` |

190 | if(s->channels == 2) { |
||

191 | s->max_framesize = 14 + ((s->blocksize * 33 + 7) >> 3); |
||

192 | ```
} else {
``` |
||

193 | s->max_framesize = 14 + (s->blocksize * s->channels * 2); |
||

194 | } |
||

195 | 9e96ab03 | Michael Niedermayer | |

196 | streaminfo = av_malloc(FLAC_STREAMINFO_SIZE); |
||

197 | write_streaminfo(s, streaminfo); |
||

198 | avctx->extradata = streaminfo; |
||

199 | avctx->extradata_size = FLAC_STREAMINFO_SIZE; |
||

200 | |||

201 | ```
s->frame_count = 0;
``` |
||

202 | |||

203 | avctx->coded_frame = avcodec_alloc_frame(); |
||

204 | ```
avctx->coded_frame->key_frame = 1;
``` |
||

205 | |||

206 | return 0; |
||

207 | } |
||

208 | |||

209 | f33aa120 | Michael Niedermayer | static void init_frame(FlacEncodeContext *s) |

210 | 9e96ab03 | Michael Niedermayer | { |

211 | ```
int i, ch;
``` |
||

212 | FlacFrame *frame; |
||

213 | |||

214 | frame = &s->frame; |
||

215 | |||

216 | for(i=0; i<16; i++) { |
||

217 | ```
if(s->blocksize == flac_blocksizes[i]) {
``` |
||

218 | frame->blocksize = flac_blocksizes[i]; |
||

219 | ```
frame->bs_code[0] = i;
``` |
||

220 | frame->bs_code[1] = 0; |
||

221 | ```
break;
``` |
||

222 | } |
||

223 | } |
||

224 | if(i == 16) { |
||

225 | frame->blocksize = s->blocksize; |
||

226 | if(frame->blocksize <= 256) { |
||

227 | frame->bs_code[0] = 6; |
||

228 | frame->bs_code[1] = frame->blocksize-1; |
||

229 | ```
} else {
``` |
||

230 | frame->bs_code[0] = 7; |
||

231 | frame->bs_code[1] = frame->blocksize-1; |
||

232 | } |
||

233 | } |
||

234 | |||

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

236 | ```
frame->subframes[ch].obits = 16;
``` |
||

237 | } |
||

238 | } |
||

239 | |||

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

241 | ```
* Copy channel-interleaved input samples into separate subframes
``` |
||

242 | ```
*/
``` |
||

243 | static void copy_samples(FlacEncodeContext *s, int16_t *samples) |
||

244 | { |
||

245 | ```
int i, j, ch;
``` |
||

246 | FlacFrame *frame; |
||

247 | |||

248 | frame = &s->frame; |
||

249 | for(i=0,j=0; i<frame->blocksize; i++) { |
||

250 | for(ch=0; ch<s->channels; ch++,j++) { |
||

251 | frame->subframes[ch].samples[i] = samples[j]; |
||

252 | } |
||

253 | } |
||

254 | } |
||

255 | |||

256 | e71bcc37 | Justin Ruggles | |

257 | #define rice_encode_count(sum, n, k) (((n)*((k)+1))+((sum-(n>>1))>>(k))) |
||

258 | |||

259 | static int find_optimal_param(uint32_t sum, int n) |
||

260 | { |
||

261 | ```
int k, k_opt;
``` |
||

262 | uint32_t nbits, nbits_opt; |
||

263 | |||

264 | ```
k_opt = 0;
``` |
||

265 | ```
nbits_opt = rice_encode_count(sum, n, 0);
``` |
||

266 | for(k=1; k<=14; k++) { |
||

267 | nbits = rice_encode_count(sum, n, k); |
||

268 | ```
if(nbits < nbits_opt) {
``` |
||

269 | nbits_opt = nbits; |
||

270 | k_opt = k; |
||

271 | } |
||

272 | } |
||

273 | ```
return k_opt;
``` |
||

274 | } |
||

275 | |||

276 | static uint32_t calc_optimal_rice_params(RiceContext *rc, int porder, |
||

277 | uint32_t *sums, int n, int pred_order) |
||

278 | { |
||

279 | ```
int i;
``` |
||

280 | ```
int k, cnt, part;
``` |
||

281 | uint32_t all_bits; |
||

282 | |||

283 | ```
part = (1 << porder);
``` |
||

284 | ```
all_bits = 0;
``` |
||

285 | |||

286 | cnt = (n >> porder) - pred_order; |
||

287 | for(i=0; i<part; i++) { |
||

288 | if(i == 1) cnt = (n >> porder); |
||

289 | k = find_optimal_param(sums[i], cnt); |
||

290 | rc->params[i] = k; |
||

291 | all_bits += rice_encode_count(sums[i], cnt, k); |
||

292 | } |
||

293 | ```
all_bits += (4 * part);
``` |
||

294 | |||

295 | rc->porder = porder; |
||

296 | |||

297 | ```
return all_bits;
``` |
||

298 | } |
||

299 | |||

300 | static void calc_sums(int pmax, uint32_t *data, int n, int pred_order, |
||

301 | ```
uint32_t sums[][256])
``` |
||

302 | { |
||

303 | ```
int i, j;
``` |
||

304 | ```
int parts, cnt;
``` |
||

305 | uint32_t *res; |
||

306 | |||

307 | ```
/* sums for highest level */
``` |
||

308 | ```
parts = (1 << pmax);
``` |
||

309 | res = &data[pred_order]; |
||

310 | cnt = (n >> pmax) - pred_order; |
||

311 | for(i=0; i<parts; i++) { |
||

312 | if(i == 1) cnt = (n >> pmax); |
||

313 | if(i > 0) res = &data[i*cnt]; |
||

314 | ```
sums[pmax][i] = 0;
``` |
||

315 | for(j=0; j<cnt; j++) { |
||

316 | sums[pmax][i] += res[j]; |
||

317 | } |
||

318 | } |
||

319 | ```
/* sums for lower levels */
``` |
||

320 | for(i=pmax-1; i>=0; i--) { |
||

321 | ```
parts = (1 << i);
``` |
||

322 | for(j=0; j<parts; j++) { |
||

323 | sums[i][j] = sums[i+1][2*j] + sums[i+1][2*j+1]; |
||

324 | } |
||

325 | } |
||

326 | } |
||

327 | |||

328 | static uint32_t calc_rice_params(RiceContext *rc, int pmax, int32_t *data, |
||

329 | int n, int pred_order) |
||

330 | { |
||

331 | ```
int i;
``` |
||

332 | uint32_t bits, opt_bits; |
||

333 | ```
int opt_porder;
``` |
||

334 | RiceContext opt_rc; |
||

335 | uint32_t *udata; |
||

336 | uint32_t sums[9][256]; |
||

337 | |||

338 | assert(pmax >= 0 && pmax <= 8); |
||

339 | |||

340 | ```
udata = av_malloc(n * sizeof(uint32_t));
``` |
||

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

342 | udata[i] = (2*data[i]) ^ (data[i]>>31); |
||

343 | } |
||

344 | |||

345 | calc_sums(pmax, udata, n, pred_order, sums); |
||

346 | |||

347 | ```
opt_porder = 0;
``` |
||

348 | opt_bits = UINT32_MAX; |
||

349 | for(i=0; i<=pmax; i++) { |
||

350 | bits = calc_optimal_rice_params(rc, i, sums[i], n, pred_order); |
||

351 | ```
if(bits < opt_bits) {
``` |
||

352 | opt_bits = bits; |
||

353 | opt_porder = i; |
||

354 | ```
memcpy(&opt_rc, rc, sizeof(RiceContext));
``` |
||

355 | } |
||

356 | } |
||

357 | ```
if(opt_porder != pmax) {
``` |
||

358 | ```
memcpy(rc, &opt_rc, sizeof(RiceContext));
``` |
||

359 | } |
||

360 | |||

361 | av_freep(&udata); |
||

362 | ```
return opt_bits;
``` |
||

363 | } |
||

364 | |||

365 | static uint32_t calc_rice_params_fixed(RiceContext *rc, int pmax, int32_t *data, |
||

366 | int n, int pred_order, int bps) |
||

367 | { |
||

368 | uint32_t bits; |
||

369 | ```
bits = pred_order*bps + 6;
``` |
||

370 | bits += calc_rice_params(rc, pmax, data, n, pred_order); |
||

371 | ```
return bits;
``` |
||

372 | } |
||

373 | |||

374 | static void encode_residual_verbatim(int32_t *res, int32_t *smp, int n) |
||

375 | { |
||

376 | ```
assert(n > 0);
``` |
||

377 | ```
memcpy(res, smp, n * sizeof(int32_t));
``` |
||

378 | } |
||

379 | |||

380 | static void encode_residual_fixed(int32_t *res, int32_t *smp, int n, int order) |
||

381 | { |
||

382 | ```
int i;
``` |
||

383 | |||

384 | for(i=0; i<order; i++) { |
||

385 | res[i] = smp[i]; |
||

386 | } |
||

387 | |||

388 | if(order==0){ |
||

389 | ```
for(i=order; i<n; i++)
``` |
||

390 | res[i]= smp[i]; |
||

391 | }else if(order==1){ |
||

392 | ```
for(i=order; i<n; i++)
``` |
||

393 | ```
res[i]= smp[i] - smp[i-1];
``` |
||

394 | }else if(order==2){ |
||

395 | ```
for(i=order; i<n; i++)
``` |
||

396 | res[i]= smp[i] - 2*smp[i-1] + smp[i-2]; |
||

397 | }else if(order==3){ |
||

398 | ```
for(i=order; i<n; i++)
``` |
||

399 | res[i]= smp[i] - 3*smp[i-1] + 3*smp[i-2] - smp[i-3]; |
||

400 | ```
}else{
``` |
||

401 | ```
for(i=order; i<n; i++)
``` |
||

402 | res[i]= smp[i] - 4*smp[i-1] + 6*smp[i-2] - 4*smp[i-3] + smp[i-4]; |
||

403 | } |
||

404 | } |
||

405 | |||

406 | static int get_max_p_order(int max_porder, int n, int order) |
||

407 | { |
||

408 | ```
int porder, max_parts;
``` |
||

409 | |||

410 | porder = max_porder; |
||

411 | while(porder > 0) { |
||

412 | ```
max_parts = (1 << porder);
``` |
||

413 | ```
if(!(n % max_parts) && (n > max_parts*order)) {
``` |
||

414 | ```
break;
``` |
||

415 | } |
||

416 | porder--; |
||

417 | } |
||

418 | ```
return porder;
``` |
||

419 | } |
||

420 | |||

421 | static int encode_residual(FlacEncodeContext *ctx, int ch) |
||

422 | { |
||

423 | ```
int i, opt_order, porder, max_porder, n;
``` |
||

424 | FlacFrame *frame; |
||

425 | FlacSubframe *sub; |
||

426 | ```
uint32_t bits[5];
``` |
||

427 | int32_t *res, *smp; |
||

428 | |||

429 | frame = &ctx->frame; |
||

430 | sub = &frame->subframes[ch]; |
||

431 | res = sub->residual; |
||

432 | smp = sub->samples; |
||

433 | n = frame->blocksize; |
||

434 | |||

435 | ```
/* CONSTANT */
``` |
||

436 | for(i=1; i<n; i++) { |
||

437 | if(smp[i] != smp[0]) break; |
||

438 | } |
||

439 | ```
if(i == n) {
``` |
||

440 | sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; |
||

441 | res[0] = smp[0]; |
||

442 | ```
return sub->obits;
``` |
||

443 | } |
||

444 | |||

445 | ```
/* VERBATIM */
``` |
||

446 | if(n < 5) { |
||

447 | sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; |
||

448 | encode_residual_verbatim(res, smp, n); |
||

449 | ```
return sub->obits * n;
``` |
||

450 | } |
||

451 | |||

452 | ```
max_porder = 3;
``` |
||

453 | |||

454 | ```
/* FIXED */
``` |
||

455 | ```
opt_order = 0;
``` |
||

456 | ```
bits[0] = UINT32_MAX;
``` |
||

457 | for(i=0; i<=4; i++) { |
||

458 | encode_residual_fixed(res, smp, n, i); |
||

459 | porder = get_max_p_order(max_porder, n, i); |
||

460 | bits[i] = calc_rice_params_fixed(&sub->rc, porder, res, n, i, sub->obits); |
||

461 | ```
if(bits[i] < bits[opt_order]) {
``` |
||

462 | opt_order = i; |
||

463 | } |
||

464 | } |
||

465 | sub->order = opt_order; |
||

466 | sub->type = FLAC_SUBFRAME_FIXED; |
||

467 | sub->type_code = sub->type | sub->order; |
||

468 | if(sub->order != 4) { |
||

469 | encode_residual_fixed(res, smp, n, sub->order); |
||

470 | porder = get_max_p_order(max_porder, n, sub->order); |
||

471 | calc_rice_params_fixed(&sub->rc, porder, res, n, sub->order, sub->obits); |
||

472 | } |
||

473 | ```
return bits[sub->order];
``` |
||

474 | } |
||

475 | |||

476 | static int encode_residual_v(FlacEncodeContext *ctx, int ch) |
||

477 | { |
||

478 | ```
int i, n;
``` |
||

479 | FlacFrame *frame; |
||

480 | FlacSubframe *sub; |
||

481 | int32_t *res, *smp; |
||

482 | |||

483 | frame = &ctx->frame; |
||

484 | sub = &frame->subframes[ch]; |
||

485 | res = sub->residual; |
||

486 | smp = sub->samples; |
||

487 | n = frame->blocksize; |
||

488 | |||

489 | ```
/* CONSTANT */
``` |
||

490 | for(i=1; i<n; i++) { |
||

491 | if(smp[i] != smp[0]) break; |
||

492 | } |
||

493 | ```
if(i == n) {
``` |
||

494 | sub->type = sub->type_code = FLAC_SUBFRAME_CONSTANT; |
||

495 | res[0] = smp[0]; |
||

496 | ```
return sub->obits;
``` |
||

497 | } |
||

498 | |||

499 | ```
/* VERBATIM */
``` |
||

500 | sub->type = sub->type_code = FLAC_SUBFRAME_VERBATIM; |
||

501 | encode_residual_verbatim(res, smp, n); |
||

502 | ```
return sub->obits * n;
``` |
||

503 | } |
||

504 | |||

505 | f33aa120 | Michael Niedermayer | static int estimate_stereo_mode(int32_t *left_ch, int32_t *right_ch, int n) |

506 | { |
||

507 | ```
int i, best;
``` |
||

508 | int32_t lt, rt; |
||

509 | e71bcc37 | Justin Ruggles | ```
uint64_t sum[4];
``` |

510 | f33aa120 | Michael Niedermayer | ```
uint64_t score[4];
``` |

511 | e71bcc37 | Justin Ruggles | ```
int k;
``` |

512 | f33aa120 | Michael Niedermayer | |

513 | ```
/* calculate sum of squares for each channel */
``` |
||

514 | e71bcc37 | Justin Ruggles | sum[0] = sum[1] = sum[2] = sum[3] = 0; |

515 | f33aa120 | Michael Niedermayer | for(i=2; i<n; i++) { |

516 | lt = left_ch[i] - 2*left_ch[i-1] + left_ch[i-2]; |
||

517 | rt = right_ch[i] - 2*right_ch[i-1] + right_ch[i-2]; |
||

518 | e71bcc37 | Justin Ruggles | sum[2] += ABS((lt + rt) >> 1); |

519 | ```
sum[3] += ABS(lt - rt);
``` |
||

520 | ```
sum[0] += ABS(lt);
``` |
||

521 | ```
sum[1] += ABS(rt);
``` |
||

522 | } |
||

523 | for(i=0; i<4; i++) { |
||

524 | ```
k = find_optimal_param(2*sum[i], n);
``` |
||

525 | ```
sum[i] = rice_encode_count(2*sum[i], n, k);
``` |
||

526 | f33aa120 | Michael Niedermayer | } |

527 | |||

528 | ```
/* calculate score for each mode */
``` |
||

529 | e71bcc37 | Justin Ruggles | score[0] = sum[0] + sum[1]; |

530 | score[1] = sum[0] + sum[3]; |
||

531 | score[2] = sum[1] + sum[3]; |
||

532 | score[3] = sum[2] + sum[3]; |
||

533 | f33aa120 | Michael Niedermayer | |

534 | ```
/* return mode with lowest score */
``` |
||

535 | ```
best = 0;
``` |
||

536 | for(i=1; i<4; i++) { |
||

537 | ```
if(score[i] < score[best]) {
``` |
||

538 | best = i; |
||

539 | } |
||

540 | } |
||

541 | if(best == 0) { |
||

542 | ```
return FLAC_CHMODE_LEFT_RIGHT;
``` |
||

543 | } else if(best == 1) { |
||

544 | ```
return FLAC_CHMODE_LEFT_SIDE;
``` |
||

545 | } else if(best == 2) { |
||

546 | ```
return FLAC_CHMODE_RIGHT_SIDE;
``` |
||

547 | ```
} else {
``` |
||

548 | ```
return FLAC_CHMODE_MID_SIDE;
``` |
||

549 | } |
||

550 | } |
||

551 | |||

552 | ```
/**
``` |
||

553 | ```
* Perform stereo channel decorrelation
``` |
||

554 | ```
*/
``` |
||

555 | static void channel_decorrelation(FlacEncodeContext *ctx) |
||

556 | { |
||

557 | FlacFrame *frame; |
||

558 | int32_t *left, *right; |
||

559 | ```
int i, n;
``` |
||

560 | |||

561 | frame = &ctx->frame; |
||

562 | n = frame->blocksize; |
||

563 | ```
left = frame->subframes[0].samples;
``` |
||

564 | ```
right = frame->subframes[1].samples;
``` |
||

565 | |||

566 | if(ctx->channels != 2) { |
||

567 | frame->ch_mode = FLAC_CHMODE_NOT_STEREO; |
||

568 | ```
return;
``` |
||

569 | } |
||

570 | |||

571 | frame->ch_mode = estimate_stereo_mode(left, right, n); |
||

572 | |||

573 | ```
/* perform decorrelation and adjust bits-per-sample */
``` |
||

574 | ```
if(frame->ch_mode == FLAC_CHMODE_LEFT_RIGHT) {
``` |
||

575 | ```
return;
``` |
||

576 | } |
||

577 | ```
if(frame->ch_mode == FLAC_CHMODE_MID_SIDE) {
``` |
||

578 | int32_t tmp; |
||

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

580 | tmp = left[i]; |
||

581 | ```
left[i] = (tmp + right[i]) >> 1;
``` |
||

582 | right[i] = tmp - right[i]; |
||

583 | } |
||

584 | ```
frame->subframes[1].obits++;
``` |
||

585 | } else if(frame->ch_mode == FLAC_CHMODE_LEFT_SIDE) { |
||

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

587 | right[i] = left[i] - right[i]; |
||

588 | } |
||

589 | ```
frame->subframes[1].obits++;
``` |
||

590 | ```
} else {
``` |
||

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

592 | left[i] -= right[i]; |
||

593 | } |
||

594 | ```
frame->subframes[0].obits++;
``` |
||

595 | } |
||

596 | } |
||

597 | |||

598 | e71bcc37 | Justin Ruggles | static void put_sbits(PutBitContext *pb, int bits, int32_t val) |

599 | 9e96ab03 | Michael Niedermayer | { |

600 | assert(bits >= 0 && bits <= 31); |
||

601 | d1015e88 | Michael Niedermayer | |

602 | put_bits(pb, bits, val & ((1<<bits)-1)); |
||

603 | 9e96ab03 | Michael Niedermayer | } |

604 | |||

605 | e71bcc37 | Justin Ruggles | static void write_utf8(PutBitContext *pb, uint32_t val) |

606 | 9e96ab03 | Michael Niedermayer | { |

607 | d1015e88 | Michael Niedermayer | ```
int bytes, shift;
``` |

608 | 9e96ab03 | Michael Niedermayer | |

609 | d1015e88 | Michael Niedermayer | if(val < 0x80){ |

610 | 9e96ab03 | Michael Niedermayer | ```
put_bits(pb, 8, val);
``` |

611 | ```
return;
``` |
||

612 | } |
||

613 | |||

614 | 6c35b4de | Michael Niedermayer | bytes= (av_log2(val)+4) / 5; |

615 | 9e96ab03 | Michael Niedermayer | shift = (bytes - 1) * 6; |

616 | d1015e88 | Michael Niedermayer | put_bits(pb, 8, (256 - (256>>bytes)) | (val >> shift)); |

617 | while(shift >= 6){ |
||

618 | 9e96ab03 | Michael Niedermayer | ```
shift -= 6;
``` |

619 | put_bits(pb, 8, 0x80 | ((val >> shift) & 0x3F)); |
||

620 | } |
||

621 | } |
||

622 | |||

623 | e71bcc37 | Justin Ruggles | static void output_frame_header(FlacEncodeContext *s) |

624 | 9e96ab03 | Michael Niedermayer | { |

625 | FlacFrame *frame; |
||

626 | ```
int crc;
``` |
||

627 | |||

628 | frame = &s->frame; |
||

629 | |||

630 | put_bits(&s->pb, 16, 0xFFF8); |
||

631 | put_bits(&s->pb, 4, frame->bs_code[0]); |
||

632 | put_bits(&s->pb, 4, s->sr_code[0]); |
||

633 | ```
if(frame->ch_mode == FLAC_CHMODE_NOT_STEREO) {
``` |
||

634 | ```
put_bits(&s->pb, 4, s->ch_code);
``` |
||

635 | ```
} else {
``` |
||

636 | ```
put_bits(&s->pb, 4, frame->ch_mode);
``` |
||

637 | } |
||

638 | put_bits(&s->pb, 3, 4); /* bits-per-sample code */ |
||

639 | put_bits(&s->pb, 1, 0); |
||

640 | write_utf8(&s->pb, s->frame_count); |
||

641 | f33aa120 | Michael Niedermayer | if(frame->bs_code[0] == 6) { |

642 | put_bits(&s->pb, 8, frame->bs_code[1]); |
||

643 | } else if(frame->bs_code[0] == 7) { |
||

644 | put_bits(&s->pb, 16, frame->bs_code[1]); |
||

645 | 9e96ab03 | Michael Niedermayer | } |

646 | f33aa120 | Michael Niedermayer | if(s->sr_code[0] == 12) { |

647 | put_bits(&s->pb, 8, s->sr_code[1]); |
||

648 | } else if(s->sr_code[0] > 12) { |
||

649 | put_bits(&s->pb, 16, s->sr_code[1]); |
||

650 | 9e96ab03 | Michael Niedermayer | } |

651 | flush_put_bits(&s->pb); |
||

652 | crc = av_crc(av_crc07, 0, s->pb.buf, put_bits_count(&s->pb)>>3); |
||

653 | ```
put_bits(&s->pb, 8, crc);
``` |
||

654 | } |
||

655 | |||

656 | e71bcc37 | Justin Ruggles | static void output_subframe_constant(FlacEncodeContext *s, int ch) |

657 | { |
||

658 | FlacSubframe *sub; |
||

659 | int32_t res; |
||

660 | |||

661 | sub = &s->frame.subframes[ch]; |
||

662 | ```
res = sub->residual[0];
``` |
||

663 | put_sbits(&s->pb, sub->obits, res); |
||

664 | } |
||

665 | |||

666 | 9e96ab03 | Michael Niedermayer | static void output_subframe_verbatim(FlacEncodeContext *s, int ch) |

667 | { |
||

668 | ```
int i;
``` |
||

669 | FlacFrame *frame; |
||

670 | FlacSubframe *sub; |
||

671 | int32_t res; |
||

672 | |||

673 | frame = &s->frame; |
||

674 | sub = &frame->subframes[ch]; |
||

675 | |||

676 | for(i=0; i<frame->blocksize; i++) { |
||

677 | res = sub->residual[i]; |
||

678 | put_sbits(&s->pb, sub->obits, res); |
||

679 | } |
||

680 | } |
||

681 | |||

682 | e71bcc37 | Justin Ruggles | static void output_residual(FlacEncodeContext *ctx, int ch) |

683 | 9e96ab03 | Michael Niedermayer | { |

684 | e71bcc37 | Justin Ruggles | ```
int i, j, p, n, parts;
``` |

685 | 9e96ab03 | Michael Niedermayer | ```
int k, porder, psize, res_cnt;
``` |

686 | FlacFrame *frame; |
||

687 | FlacSubframe *sub; |
||

688 | e71bcc37 | Justin Ruggles | int32_t *res; |

689 | 9e96ab03 | Michael Niedermayer | |

690 | frame = &ctx->frame; |
||

691 | sub = &frame->subframes[ch]; |
||

692 | e71bcc37 | Justin Ruggles | res = sub->residual; |

693 | n = frame->blocksize; |
||

694 | 9e96ab03 | Michael Niedermayer | |

695 | ```
/* rice-encoded block */
``` |
||

696 | put_bits(&ctx->pb, 2, 0); |
||

697 | |||

698 | ```
/* partition order */
``` |
||

699 | e71bcc37 | Justin Ruggles | porder = sub->rc.porder; |

700 | psize = n >> porder; |
||

701 | ```
parts = (1 << porder);
``` |
||

702 | 9e96ab03 | Michael Niedermayer | ```
put_bits(&ctx->pb, 4, porder);
``` |

703 | res_cnt = psize - sub->order; |
||

704 | |||

705 | ```
/* residual */
``` |
||

706 | j = sub->order; |
||

707 | e71bcc37 | Justin Ruggles | for(p=0; p<parts; p++) { |

708 | k = sub->rc.params[p]; |
||

709 | 9e96ab03 | Michael Niedermayer | ```
put_bits(&ctx->pb, 4, k);
``` |

710 | if(p == 1) res_cnt = psize; |
||

711 | e71bcc37 | Justin Ruggles | for(i=0; i<res_cnt && j<n; i++, j++) { |

712 | ```
set_sr_golomb_flac(&ctx->pb, res[j], k, INT32_MAX, 0);
``` |
||

713 | 9e96ab03 | Michael Niedermayer | } |

714 | } |
||

715 | } |
||

716 | |||

717 | e71bcc37 | Justin Ruggles | static void output_subframe_fixed(FlacEncodeContext *ctx, int ch) |

718 | 9e96ab03 | Michael Niedermayer | { |

719 | ```
int i;
``` |
||

720 | FlacFrame *frame; |
||

721 | FlacSubframe *sub; |
||

722 | |||

723 | frame = &ctx->frame; |
||

724 | sub = &frame->subframes[ch]; |
||

725 | |||

726 | ```
/* warm-up samples */
``` |
||

727 | for(i=0; i<sub->order; i++) { |
||

728 | put_sbits(&ctx->pb, sub->obits, sub->residual[i]); |
||

729 | } |
||

730 | |||

731 | ```
/* residual */
``` |
||

732 | output_residual(ctx, ch); |
||

733 | } |
||

734 | |||

735 | static void output_subframes(FlacEncodeContext *s) |
||

736 | { |
||

737 | FlacFrame *frame; |
||

738 | FlacSubframe *sub; |
||

739 | ```
int ch;
``` |
||

740 | |||

741 | frame = &s->frame; |
||

742 | |||

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

744 | sub = &frame->subframes[ch]; |
||

745 | |||

746 | ```
/* subframe header */
``` |
||

747 | put_bits(&s->pb, 1, 0); |
||

748 | ```
put_bits(&s->pb, 6, sub->type_code);
``` |
||

749 | put_bits(&s->pb, 1, 0); /* no wasted bits */ |
||

750 | |||

751 | ```
/* subframe */
``` |
||

752 | e71bcc37 | Justin Ruggles | ```
if(sub->type == FLAC_SUBFRAME_CONSTANT) {
``` |

753 | output_subframe_constant(s, ch); |
||

754 | } else if(sub->type == FLAC_SUBFRAME_VERBATIM) { |
||

755 | 9e96ab03 | Michael Niedermayer | output_subframe_verbatim(s, ch); |

756 | e71bcc37 | Justin Ruggles | } else if(sub->type == FLAC_SUBFRAME_FIXED) { |

757 | 9e96ab03 | Michael Niedermayer | output_subframe_fixed(s, ch); |

758 | } |
||

759 | } |
||

760 | } |
||

761 | |||

762 | static void output_frame_footer(FlacEncodeContext *s) |
||

763 | { |
||

764 | ```
int crc;
``` |
||

765 | flush_put_bits(&s->pb); |
||

766 | crc = bswap_16(av_crc(av_crc8005, 0, s->pb.buf, put_bits_count(&s->pb)>>3)); |
||

767 | ```
put_bits(&s->pb, 16, crc);
``` |
||

768 | flush_put_bits(&s->pb); |
||

769 | } |
||

770 | |||

771 | static int flac_encode_frame(AVCodecContext *avctx, uint8_t *frame, |
||

772 | int buf_size, void *data) |
||

773 | { |
||

774 | ```
int ch;
``` |
||

775 | FlacEncodeContext *s; |
||

776 | int16_t *samples = data; |
||

777 | ```
int out_bytes;
``` |
||

778 | |||

779 | s = avctx->priv_data; |
||

780 | |||

781 | s->blocksize = avctx->frame_size; |
||

782 | f33aa120 | Michael Niedermayer | init_frame(s); |

783 | 9e96ab03 | Michael Niedermayer | |

784 | copy_samples(s, samples); |
||

785 | |||

786 | f33aa120 | Michael Niedermayer | channel_decorrelation(s); |

787 | |||

788 | 9e96ab03 | Michael Niedermayer | for(ch=0; ch<s->channels; ch++) { |

789 | encode_residual(s, ch); |
||

790 | } |
||

791 | init_put_bits(&s->pb, frame, buf_size); |
||

792 | output_frame_header(s); |
||

793 | output_subframes(s); |
||

794 | output_frame_footer(s); |
||

795 | ```
out_bytes = put_bits_count(&s->pb) >> 3;
``` |
||

796 | |||

797 | ```
if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
``` |
||

798 | ```
/* frame too large. use verbatim mode */
``` |
||

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

800 | e71bcc37 | Justin Ruggles | encode_residual_v(s, ch); |

801 | 9e96ab03 | Michael Niedermayer | } |

802 | init_put_bits(&s->pb, frame, buf_size); |
||

803 | output_frame_header(s); |
||

804 | output_subframes(s); |
||

805 | output_frame_footer(s); |
||

806 | ```
out_bytes = put_bits_count(&s->pb) >> 3;
``` |
||

807 | |||

808 | ```
if(out_bytes > s->max_framesize || out_bytes >= buf_size) {
``` |
||

809 | ```
/* still too large. must be an error. */
``` |
||

810 | ```
av_log(avctx, AV_LOG_ERROR, "error encoding frame\n");
``` |
||

811 | return -1; |
||

812 | } |
||

813 | } |
||

814 | |||

815 | s->frame_count++; |
||

816 | ```
return out_bytes;
``` |
||

817 | } |
||

818 | |||

819 | static int flac_encode_close(AVCodecContext *avctx) |
||

820 | { |
||

821 | f33aa120 | Michael Niedermayer | av_freep(&avctx->extradata); |

822 | ```
avctx->extradata_size = 0;
``` |
||

823 | 9e96ab03 | Michael Niedermayer | av_freep(&avctx->coded_frame); |

824 | return 0; |
||

825 | } |
||

826 | |||

827 | AVCodec flac_encoder = { |
||

828 | ```
"flac",
``` |
||

829 | CODEC_TYPE_AUDIO, |
||

830 | CODEC_ID_FLAC, |
||

831 | ```
sizeof(FlacEncodeContext),
``` |
||

832 | flac_encode_init, |
||

833 | flac_encode_frame, |
||

834 | flac_encode_close, |
||

835 | ```
NULL,
``` |
||

836 | .capabilities = CODEC_CAP_SMALL_LAST_FRAME, |
||

837 | }; |