for (int i = 0; i < m; i++) { \
for (int j = 0; j < N; j++) \
fft##N##in[j] = in[in_map[i*N + j]]; \
- fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
+ fft##N(s->tmp + s->revtab_c[i], fft##N##in, m); \
} \
\
for (int i = 0; i < N; i++) \
do {
tmp = out[src];
- dst = s->revtab[src];
+ dst = s->revtab_c[src];
do {
FFSWAP(FFTComplex, tmp, out[dst]);
- dst = s->revtab[dst];
+ dst = s->revtab_c[dst];
} while (dst != src); /* Can be > as well, but is less predictable */
out[dst] = tmp;
} while ((src = *inplace_idx++));
} else {
for (int i = 0; i < m; i++)
- out[i] = in[s->revtab[i]];
+ out[i] = in[s->revtab_c[i]];
}
fft_dispatch[mb](out);
FFTComplex tmp = { in2[-k*stride], in1[k*stride] }; \
CMUL3(fft##N##in[j], tmp, exp[k >> 1]); \
} \
- fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
+ fft##N(s->tmp + s->revtab_c[i], fft##N##in, m); \
} \
\
for (int i = 0; i < N; i++) \
CMUL(fft##N##in[j].im, fft##N##in[j].re, tmp.re, tmp.im, \
exp[k >> 1].re, exp[k >> 1].im); \
} \
- fft##N(s->tmp + s->revtab[i], fft##N##in, m); \
+ fft##N(s->tmp + s->revtab_c[i], fft##N##in, m); \
} \
\
for (int i = 0; i < N; i++) \
for (int i = 0; i < m; i++) {
FFTComplex tmp = { in2[-2*i*stride], in1[2*i*stride] };
- CMUL3(z[s->revtab[i]], tmp, exp[i]);
+ CMUL3(z[s->revtab_c[i]], tmp, exp[i]);
}
fftp(z);
tmp.re = FOLD(-src[ len4 + k], -src[5*len4 - 1 - k]);
tmp.im = FOLD( src[-len4 + k], -src[1*len3 - 1 - k]);
}
- CMUL(z[s->revtab[i]].im, z[s->revtab[i]].re, tmp.re, tmp.im,
+ CMUL(z[s->revtab_c[i]].im, z[s->revtab_c[i]].re, tmp.re, tmp.im,
exp[i].re, exp[i].im);
}
}
}
+static void full_imdct_wrapper_fn(AVTXContext *s, void *_dst, void *_src,
+ ptrdiff_t stride)
+{
+ int len = s->m*s->n*4;
+ int len2 = len >> 1;
+ int len4 = len >> 2;
+ FFTSample *dst = _dst;
+
+ s->top_tx(s, dst + len4, _src, stride);
+
+ stride /= sizeof(*dst);
+
+ for (int i = 0; i < len4; i++) {
+ dst[ i*stride] = -dst[(len2 - i - 1)*stride];
+ dst[(len - i - 1)*stride] = dst[(len2 + i + 0)*stride];
+ }
+}
+
static int gen_mdct_exptab(AVTXContext *s, int len4, double scale)
{
const double theta = (scale < 0 ? len4 : 0) + 1.0/8.0;
if (is_mdct) {
s->scale = *((SCALE_TYPE *)scale);
*tx = inv ? naive_imdct : naive_mdct;
+ if (inv && (flags & AV_TX_FULL_IMDCT)) {
+ s->top_tx = *tx;
+ *tx = full_imdct_wrapper_fn;
+ }
}
return 0;
}
if (flags & AV_TX_INPLACE) {
if (is_mdct) /* In-place MDCTs are not supported yet */
return AVERROR(ENOSYS);
- if ((err = ff_tx_gen_ptwo_inplace_revtab_idx(s)))
+ if ((err = ff_tx_gen_ptwo_inplace_revtab_idx(s, s->revtab_c)))
return err;
}
for (int i = 4; i <= av_log2(m); i++)
init_cos_tabs(i);
}
- if (is_mdct)
+ if (is_mdct) {
+ if (inv && (flags & AV_TX_FULL_IMDCT)) {
+ s->top_tx = *tx;
+ *tx = full_imdct_wrapper_fn;
+ }
return gen_mdct_exptab(s, n*m, *((SCALE_TYPE *)scale));
+ }
return 0;
}