This increases the accuracy of coefficients, leading to improved quality.
Rescaling of the coefficients to full 25-bit accuracy is done rather than
offsetting the exponent values. This requires coefficient scaling to be done
before determining the rematrixing strategy. Also, the rematrixing strategy
calculation must use 64-bit math to prevent overflow due to the higher
precision coefficients.
| ... | ... |
@@ -78,7 +78,7 @@ typedef struct AC3Block {
|
| 78 | 78 |
int16_t **band_psd; ///< psd per critical band |
| 79 | 79 |
int16_t **mask; ///< masking curve |
| 80 | 80 |
uint16_t **qmant; ///< quantized mantissas |
| 81 |
- int8_t exp_shift[AC3_MAX_CHANNELS]; ///< exponent shift values |
|
| 81 |
+ uint8_t coeff_shift[AC3_MAX_CHANNELS]; ///< fixed-point coefficient shift values |
|
| 82 | 82 |
uint8_t new_rematrixing_strategy; ///< send new rematrixing flags in this block |
| 83 | 83 |
uint8_t rematrixing_flags[4]; ///< rematrixing flags |
| 84 | 84 |
} AC3Block; |
| ... | ... |
@@ -269,7 +269,7 @@ static void apply_mdct(AC3EncodeContext *s) |
| 269 | 269 |
|
| 270 | 270 |
apply_window(&s->dsp, s->windowed_samples, input_samples, s->mdct.window, AC3_WINDOW_SIZE); |
| 271 | 271 |
|
| 272 |
- block->exp_shift[ch] = normalize_samples(s); |
|
| 272 |
+ block->coeff_shift[ch] = normalize_samples(s); |
|
| 273 | 273 |
|
| 274 | 274 |
mdct512(&s->mdct, block->mdct_coef[ch], s->windowed_samples); |
| 275 | 275 |
} |
| ... | ... |
@@ -328,10 +328,10 @@ static void compute_rematrixing_strategy(AC3EncodeContext *s) |
| 328 | 328 |
CoefType rt = block->mdct_coef[1][i]; |
| 329 | 329 |
CoefType md = lt + rt; |
| 330 | 330 |
CoefType sd = lt - rt; |
| 331 |
- sum[0] += lt * lt; |
|
| 332 |
- sum[1] += rt * rt; |
|
| 333 |
- sum[2] += md * md; |
|
| 334 |
- sum[3] += sd * sd; |
|
| 331 |
+ MAC_COEF(sum[0], lt, lt); |
|
| 332 |
+ MAC_COEF(sum[1], rt, rt); |
|
| 333 |
+ MAC_COEF(sum[2], md, md); |
|
| 334 |
+ MAC_COEF(sum[3], sd, sd); |
|
| 335 | 335 |
} |
| 336 | 336 |
|
| 337 | 337 |
/* compare sums to determine if rematrixing will be used for this band */ |
| ... | ... |
@@ -416,14 +416,13 @@ static void extract_exponents(AC3EncodeContext *s) |
| 416 | 416 |
AC3Block *block = &s->blocks[blk]; |
| 417 | 417 |
uint8_t *exp = block->exp[ch]; |
| 418 | 418 |
int32_t *coef = block->fixed_coef[ch]; |
| 419 |
- int exp_shift = block->exp_shift[ch]; |
|
| 420 | 419 |
for (i = 0; i < AC3_MAX_COEFS; i++) {
|
| 421 | 420 |
int e; |
| 422 | 421 |
int v = abs(coef[i]); |
| 423 | 422 |
if (v == 0) |
| 424 | 423 |
e = 24; |
| 425 | 424 |
else {
|
| 426 |
- e = 23 - av_log2(v) + exp_shift; |
|
| 425 |
+ e = 23 - av_log2(v); |
|
| 427 | 426 |
if (e >= 24) {
|
| 428 | 427 |
e = 24; |
| 429 | 428 |
coef[i] = 0; |
| ... | ... |
@@ -1139,7 +1138,7 @@ static inline int asym_quant(int c, int e, int qbits) |
| 1139 | 1139 |
* Quantize a set of mantissas for a single channel in a single block. |
| 1140 | 1140 |
*/ |
| 1141 | 1141 |
static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef, |
| 1142 |
- int8_t exp_shift, uint8_t *exp, |
|
| 1142 |
+ uint8_t *exp, |
|
| 1143 | 1143 |
uint8_t *bap, uint16_t *qmant, int n) |
| 1144 | 1144 |
{
|
| 1145 | 1145 |
int i; |
| ... | ... |
@@ -1147,7 +1146,7 @@ static void quantize_mantissas_blk_ch(AC3EncodeContext *s, int32_t *fixed_coef, |
| 1147 | 1147 |
for (i = 0; i < n; i++) {
|
| 1148 | 1148 |
int v; |
| 1149 | 1149 |
int c = fixed_coef[i]; |
| 1150 |
- int e = exp[i] - exp_shift; |
|
| 1150 |
+ int e = exp[i]; |
|
| 1151 | 1151 |
int b = bap[i]; |
| 1152 | 1152 |
switch (b) {
|
| 1153 | 1153 |
case 0: |
| ... | ... |
@@ -1243,7 +1242,7 @@ static void quantize_mantissas(AC3EncodeContext *s) |
| 1243 | 1243 |
s->qmant1_ptr = s->qmant2_ptr = s->qmant4_ptr = NULL; |
| 1244 | 1244 |
|
| 1245 | 1245 |
for (ch = 0; ch < s->channels; ch++) {
|
| 1246 |
- quantize_mantissas_blk_ch(s, block->fixed_coef[ch], block->exp_shift[ch], |
|
| 1246 |
+ quantize_mantissas_blk_ch(s, block->fixed_coef[ch], |
|
| 1247 | 1247 |
block->exp[ch], block->bap[ch], |
| 1248 | 1248 |
block->qmant[ch], s->nb_coefs[ch]); |
| 1249 | 1249 |
} |
| ... | ... |
@@ -1507,10 +1506,10 @@ static int ac3_encode_frame(AVCodecContext *avctx, unsigned char *frame, |
| 1507 | 1507 |
|
| 1508 | 1508 |
apply_mdct(s); |
| 1509 | 1509 |
|
| 1510 |
- compute_rematrixing_strategy(s); |
|
| 1511 |
- |
|
| 1512 | 1510 |
scale_coefficients(s); |
| 1513 | 1511 |
|
| 1512 |
+ compute_rematrixing_strategy(s); |
|
| 1513 |
+ |
|
| 1514 | 1514 |
apply_rematrixing(s); |
| 1515 | 1515 |
|
| 1516 | 1516 |
process_exponents(s); |
| ... | ... |
@@ -131,10 +131,10 @@ mdct_alloc_fail: |
| 131 | 131 |
|
| 132 | 132 |
|
| 133 | 133 |
/** Complex multiply */ |
| 134 |
-#define CMUL(pre, pim, are, aim, bre, bim) \ |
|
| 134 |
+#define CMUL(pre, pim, are, aim, bre, bim, rshift) \ |
|
| 135 | 135 |
{ \
|
| 136 |
- pre = (MUL16(are, bre) - MUL16(aim, bim)) >> 15; \ |
|
| 137 |
- pim = (MUL16(are, bim) + MUL16(bre, aim)) >> 15; \ |
|
| 136 |
+ pre = (MUL16(are, bre) - MUL16(aim, bim)) >> rshift; \ |
|
| 137 |
+ pim = (MUL16(are, bim) + MUL16(bre, aim)) >> rshift; \ |
|
| 138 | 138 |
} |
| 139 | 139 |
|
| 140 | 140 |
|
| ... | ... |
@@ -195,7 +195,7 @@ static void fft(AC3MDCTContext *mdct, IComplex *z, int ln) |
| 195 | 195 |
p++; |
| 196 | 196 |
q++; |
| 197 | 197 |
for(l = nblocks; l < np2; l += nblocks) {
|
| 198 |
- CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im); |
|
| 198 |
+ CMUL(tmp_re, tmp_im, mdct->costab[l], -mdct->sintab[l], q->re, q->im, 15); |
|
| 199 | 199 |
BF(p->re, p->im, q->re, q->im, |
| 200 | 200 |
p->re, p->im, tmp_re, tmp_im); |
| 201 | 201 |
p++; |
| ... | ... |
@@ -234,7 +234,7 @@ static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in) |
| 234 | 234 |
for (i = 0; i < n4; i++) {
|
| 235 | 235 |
re = ((int)rot[ 2*i] - (int)rot[ n-1-2*i]) >> 1; |
| 236 | 236 |
im = -((int)rot[n2+2*i] - (int)rot[n2-1-2*i]) >> 1; |
| 237 |
- CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i]); |
|
| 237 |
+ CMUL(x[i].re, x[i].im, re, im, -mdct->xcos1[i], mdct->xsin1[i], 15); |
|
| 238 | 238 |
} |
| 239 | 239 |
|
| 240 | 240 |
fft(mdct, x, mdct->nbits - 2); |
| ... | ... |
@@ -243,7 +243,7 @@ static void mdct512(AC3MDCTContext *mdct, int32_t *out, int16_t *in) |
| 243 | 243 |
for (i = 0; i < n4; i++) {
|
| 244 | 244 |
re = x[i].re; |
| 245 | 245 |
im = x[i].im; |
| 246 |
- CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i]); |
|
| 246 |
+ CMUL(out[n2-1-2*i], out[2*i], re, im, mdct->xsin1[i], mdct->xcos1[i], 0); |
|
| 247 | 247 |
} |
| 248 | 248 |
} |
| 249 | 249 |
|
| ... | ... |
@@ -295,9 +295,25 @@ static void lshift_tab(int16_t *tab, int n, unsigned int lshift) |
| 295 | 295 |
|
| 296 | 296 |
|
| 297 | 297 |
/** |
| 298 |
+ * Right-shift each value in an array of int32_t by a specified amount. |
|
| 299 |
+ * @param src input array |
|
| 300 |
+ * @param len number of values in the array |
|
| 301 |
+ * @param shift right shift amount |
|
| 302 |
+ */ |
|
| 303 |
+static void ac3_rshift_int32_c(int32_t *src, unsigned int len, unsigned int shift) |
|
| 304 |
+{
|
|
| 305 |
+ int i; |
|
| 306 |
+ |
|
| 307 |
+ if (shift > 0) {
|
|
| 308 |
+ for (i = 0; i < len; i++) |
|
| 309 |
+ src[i] >>= shift; |
|
| 310 |
+ } |
|
| 311 |
+} |
|
| 312 |
+ |
|
| 313 |
+ |
|
| 314 |
+/** |
|
| 298 | 315 |
* Normalize the input samples to use the maximum available precision. |
| 299 |
- * This assumes signed 16-bit input samples. Exponents are reduced by 9 to |
|
| 300 |
- * match the 24-bit internal precision for MDCT coefficients. |
|
| 316 |
+ * This assumes signed 16-bit input samples. |
|
| 301 | 317 |
* |
| 302 | 318 |
* @return exponent shift |
| 303 | 319 |
*/ |
| ... | ... |
@@ -305,18 +321,25 @@ static int normalize_samples(AC3EncodeContext *s) |
| 305 | 305 |
{
|
| 306 | 306 |
int v = 14 - log2_tab(s, s->windowed_samples, AC3_WINDOW_SIZE); |
| 307 | 307 |
lshift_tab(s->windowed_samples, AC3_WINDOW_SIZE, v); |
| 308 |
- return v - 9; |
|
| 308 |
+ /* +6 to right-shift from 31-bit to 25-bit */ |
|
| 309 |
+ return v + 6; |
|
| 309 | 310 |
} |
| 310 | 311 |
|
| 311 | 312 |
|
| 312 | 313 |
/** |
| 313 |
- * Scale MDCT coefficients from float to fixed-point. |
|
| 314 |
+ * Scale MDCT coefficients to 25-bit signed fixed-point. |
|
| 314 | 315 |
*/ |
| 315 | 316 |
static void scale_coefficients(AC3EncodeContext *s) |
| 316 | 317 |
{
|
| 317 |
- /* scaling/conversion is obviously not needed for the fixed-point encoder |
|
| 318 |
- since the coefficients are already fixed-point. */ |
|
| 319 |
- return; |
|
| 318 |
+ int blk, ch; |
|
| 319 |
+ |
|
| 320 |
+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
|
|
| 321 |
+ AC3Block *block = &s->blocks[blk]; |
|
| 322 |
+ for (ch = 0; ch < s->channels; ch++) {
|
|
| 323 |
+ ac3_rshift_int32_c(block->mdct_coef[ch], AC3_MAX_COEFS, |
|
| 324 |
+ block->coeff_shift[ch]); |
|
| 325 |
+ } |
|
| 326 |
+ } |
|
| 320 | 327 |
} |
| 321 | 328 |
|
| 322 | 329 |
|
| ... | ... |
@@ -4,28 +4,29 @@ ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 4 | 4 |
ret: 0 st:-1 flags:1 ts: 1.894167 |
| 5 | 5 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 6 | 6 |
ret: 0 st: 0 flags:0 ts: 0.788000 |
| 7 |
-ret: 0 st: 0 flags:1 dts:4160806.587000 pts:4160806.587000 pos: 3883 size: 116 |
|
| 7 |
+ret: 0 st: 0 flags:1 dts:12581.487000 pts:12581.487000 pos: 5822 size: 916 |
|
| 8 | 8 |
ret: 0 st: 0 flags:1 ts:-0.317000 |
| 9 | 9 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 10 | 10 |
ret: 0 st:-1 flags:0 ts: 2.576668 |
| 11 |
-ret: 0 st: 0 flags:1 dts:4160806.587000 pts:4160806.587000 pos: 3883 size: 116 |
|
| 11 |
+ret: 0 st: 0 flags:1 dts:524.800000 pts:524.800000 pos: 6155 size: 244 |
|
| 12 | 12 |
ret:-1 st:-1 flags:1 ts: 1.470835 |
| 13 | 13 |
ret: 0 st: 0 flags:0 ts: 0.365000 |
| 14 |
-ret: 0 st: 0 flags:1 dts:4160806.587000 pts:4160806.587000 pos: 3883 size: 116 |
|
| 14 |
+ret: 0 st: 0 flags:1 dts:12581.487000 pts:12581.487000 pos: 5822 size: 916 |
|
| 15 | 15 |
ret: 0 st: 0 flags:1 ts:-0.741000 |
| 16 | 16 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 17 | 17 |
ret:-1 st:-1 flags:0 ts: 2.153336 |
| 18 |
-ret:-1 st:-1 flags:1 ts: 1.047503 |
|
| 18 |
+ret: 0 st:-1 flags:1 ts: 1.047503 |
|
| 19 |
+ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
|
| 19 | 20 |
ret: 0 st: 0 flags:0 ts:-0.058000 |
| 20 | 21 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 21 |
-ret:-1 st: 0 flags:1 ts: 2.836000 |
|
| 22 |
+ret: 0 st: 0 flags:1 ts: 2.836000 |
|
| 23 |
+ret: 0 st: 0 flags:1 dts: 2.681000 pts: 2.681000 pos: 44105 size: 558 |
|
| 22 | 24 |
ret:-1 st:-1 flags:0 ts: 1.730004 |
| 23 | 25 |
ret: 0 st:-1 flags:1 ts: 0.624171 |
| 24 | 26 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 25 | 27 |
ret: 0 st: 0 flags:0 ts:-0.482000 |
| 26 | 28 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 27 |
-ret: 0 st: 0 flags:1 ts: 2.413000 |
|
| 28 |
-ret: 0 st: 0 flags:1 dts: 2.229000 pts: 2.229000 pos: 36705 size: 556 |
|
| 29 |
+ret:-1 st: 0 flags:1 ts: 2.413000 |
|
| 29 | 30 |
ret:-1 st:-1 flags:0 ts: 1.306672 |
| 30 | 31 |
ret: 0 st:-1 flags:1 ts: 0.200839 |
| 31 | 32 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| ... | ... |
@@ -33,13 +34,12 @@ ret: 0 st: 0 flags:0 ts:-0.905000 |
| 33 | 33 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 34 | 34 |
ret:-1 st: 0 flags:1 ts: 1.989000 |
| 35 | 35 |
ret: 0 st:-1 flags:0 ts: 0.883340 |
| 36 |
-ret: 0 st: 0 flags:1 dts:4160806.587000 pts:4160806.587000 pos: 3883 size: 116 |
|
| 36 |
+ret: 0 st: 0 flags:1 dts:12581.487000 pts:12581.487000 pos: 5822 size: 916 |
|
| 37 | 37 |
ret: 0 st:-1 flags:1 ts:-0.222493 |
| 38 | 38 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |
| 39 |
-ret: 0 st: 0 flags:0 ts: 2.672000 |
|
| 40 |
-ret: 0 st: 0 flags:1 dts:6354.691000 pts:6354.691000 pos: 10783 size: 304 |
|
| 39 |
+ret:-1 st: 0 flags:0 ts: 2.672000 |
|
| 41 | 40 |
ret:-1 st: 0 flags:1 ts: 1.566000 |
| 42 | 41 |
ret: 0 st:-1 flags:0 ts: 0.460008 |
| 43 |
-ret: 0 st: 0 flags:1 dts:4160806.587000 pts:4160806.587000 pos: 3883 size: 116 |
|
| 42 |
+ret: 0 st: 0 flags:1 dts:12581.487000 pts:12581.487000 pos: 5822 size: 916 |
|
| 44 | 43 |
ret: 0 st:-1 flags:1 ts:-0.645825 |
| 45 | 44 |
ret: 0 st: 0 flags:1 dts: 0.000000 pts: 0.000000 pos: 271 size: 556 |