aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJustin Ruggles <justin.ruggles@gmail.com>2010-12-14 14:52:59 +0000
committerJustin Ruggles <justin.ruggles@gmail.com>2010-12-14 14:52:59 +0000
commit0a0a8500fb1c213b6e49c6ec5dd354b150a123b0 (patch)
treedc47d30d8dea27e002ae13c63574be7ded33fbe3
parent4acc790f3ca9f48cf39caaec806796f471397fb5 (diff)
downloadffmpeg-0a0a8500fb1c213b6e49c6ec5dd354b150a123b0.tar.gz
Split applying of MDCT into several separate functions.
Originally committed as revision 25990 to svn://svn.ffmpeg.org/ffmpeg/trunk
-rw-r--r--libavcodec/ac3enc.c86
1 files changed, 61 insertions, 25 deletions
diff --git a/libavcodec/ac3enc.c b/libavcodec/ac3enc.c
index 19af922c7f..f05ff4a65b 100644
--- a/libavcodec/ac3enc.c
+++ b/libavcodec/ac3enc.c
@@ -313,6 +313,22 @@ static void mdct512(int32_t *out, int16_t *in)
/**
+ * Apply KBD window to input samples prior to MDCT.
+ */
+static void apply_window(int16_t *output, const int16_t *input,
+ const int16_t *window, int n)
+{
+ int i;
+ int n2 = n >> 1;
+
+ for (i = 0; i < n2; i++) {
+ output[i] = MUL16(input[i], window[i]) >> 15;
+ output[n-i-1] = MUL16(input[n-i-1], window[i]) >> 15;
+ }
+}
+
+
+/**
* Calculate the log2() of the maximum absolute value in an array.
* @param tab input array
* @param n number of values in the array
@@ -352,6 +368,50 @@ static void lshift_tab(int16_t *tab, int n, int lshift)
/**
+ * Normalize the input samples to use the maximum available precision.
+ * This assumes signed 16-bit input samples. Exponents are reduced by 9 to
+ * match the 24-bit internal precision for MDCT coefficients.
+ *
+ * @return exponent shift
+ */
+static int normalize_samples(AC3EncodeContext *s,
+ int16_t windowed_samples[AC3_WINDOW_SIZE])
+{
+ int v = 14 - log2_tab(windowed_samples, AC3_WINDOW_SIZE);
+ v = FFMAX(0, v);
+ lshift_tab(windowed_samples, AC3_WINDOW_SIZE, v);
+ return v - 9;
+}
+
+
+/**
+ * Apply the MDCT to input samples to generate frequency coefficients.
+ * This applies the KBD window and normalizes the input to reduce precision
+ * loss due to fixed-point calculations.
+ */
+static void apply_mdct(AC3EncodeContext *s,
+ int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE],
+ int8_t exp_shift[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS],
+ int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS])
+{
+ int blk, ch;
+ int16_t windowed_samples[AC3_WINDOW_SIZE];
+
+ for (ch = 0; ch < s->channels; ch++) {
+ for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
+ const int16_t *input_samples = &planar_samples[ch][blk * AC3_BLOCK_SIZE];
+
+ apply_window(windowed_samples, input_samples, ff_ac3_window, AC3_WINDOW_SIZE);
+
+ exp_shift[blk][ch] = normalize_samples(s, windowed_samples);
+
+ mdct512(mdct_coef[blk][ch], windowed_samples);
+ }
+ }
+}
+
+
+/**
* Calculate the sum of absolute differences (SAD) between 2 sets of exponents.
*/
static int calc_exp_diff(uint8_t *exp1, uint8_t *exp2, int n)
@@ -1117,7 +1177,6 @@ static int ac3_encode_frame(AVCodecContext *avctx,
int v;
int blk, blk1, blk2, ch, i;
int16_t planar_samples[AC3_MAX_CHANNELS][AC3_BLOCK_SIZE+AC3_FRAME_SIZE];
- int16_t windowed_samples[AC3_WINDOW_SIZE];
int32_t mdct_coef[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS][AC3_MAX_COEFS];
uint8_t exp_strategy[AC3_MAX_BLOCKS][AC3_MAX_CHANNELS];
@@ -1128,30 +1187,7 @@ static int ac3_encode_frame(AVCodecContext *avctx,
deinterleave_input_samples(s, samples, planar_samples);
- /* apply MDCT */
- for (ch = 0; ch < s->channels; ch++) {
- for (blk = 0; blk < AC3_MAX_BLOCKS; blk++) {
- int16_t *input_samples = &planar_samples[ch][blk * AC3_BLOCK_SIZE];
-
- /* apply the MDCT window */
- for (i = 0; i < AC3_BLOCK_SIZE; i++) {
- windowed_samples[i] = MUL16(input_samples[i],
- ff_ac3_window[i]) >> 15;
- windowed_samples[AC3_WINDOW_SIZE-i-1] = MUL16(input_samples[AC3_WINDOW_SIZE-i-1],
- ff_ac3_window[i]) >> 15;
- }
-
- /* Normalize the samples to use the maximum available precision */
- v = 14 - log2_tab(windowed_samples, AC3_WINDOW_SIZE);
- if (v < 0)
- v = 0;
- exp_shift[blk][ch] = v - 9;
- lshift_tab(windowed_samples, AC3_WINDOW_SIZE, v);
-
- /* do the MDCT */
- mdct512(mdct_coef[blk][ch], windowed_samples);
- }
- }
+ apply_mdct(s, planar_samples, exp_shift, mdct_coef);
/* extract exponents */
for (ch = 0; ch < s->channels; ch++) {