Browse code

ac3enc: do not right-shift fixed-point coefficients in the final MDCT stage.

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.

Justin authored on 2011/03/12 03:03:26
Showing 7 changed files
... ...
@@ -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
 
... ...
@@ -36,6 +36,8 @@ typedef int16_t SampleType;
36 36
 typedef int32_t CoefType;
37 37
 typedef int64_t CoefSumType;
38 38
 
39
+#define MAC_COEF(d,a,b) MAC64(d,a,b)
40
+
39 41
 
40 42
 /**
41 43
  * Compex number.
... ...
@@ -36,6 +36,8 @@ typedef float SampleType;
36 36
 typedef float CoefType;
37 37
 typedef float CoefSumType;
38 38
 
39
+#define MAC_COEF(d,a,b) ((d)+=(a)*(b))
40
+
39 41
 
40 42
 typedef struct AC3MDCTContext {
41 43
     const float *window;    ///< MDCT window function
... ...
@@ -1,2 +1,2 @@
1
-07bd593823ebd721b3a32ef298bdfc20 *./tests/data/acodec/ac3.rm
1
+b3a8f0a8809a58b2ece90744f06fff96 *./tests/data/acodec/ac3.rm
2 2
 98751 ./tests/data/acodec/ac3.rm
... ...
@@ -1,2 +1,2 @@
1
-d149fc272dfd21fb8908ee21d7b1651b *./tests/data/lavf/lavf.rm
1
+7da378131db880bcf2e58305d54418ec *./tests/data/lavf/lavf.rm
2 2
 346706 ./tests/data/lavf/lavf.rm
... ...
@@ -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