mirror of
https://github.com/librempeg/librempeg
synced 2024-11-23 03:28:27 +00:00
lavu/tx: add full-sized iMDCT transform flag
This commit is contained in:
parent
aa6c757d50
commit
0072a42388
@ -55,7 +55,8 @@ enum AVTXType {
|
||||
* Stride must be a non-zero multiple of sizeof(float).
|
||||
*
|
||||
* NOTE: the inverse transform is half-length, meaning the output will not
|
||||
* contain redundant data. This is what most codecs work with.
|
||||
* contain redundant data. This is what most codecs work with. To do a full
|
||||
* inverse transform, set the AV_TX_FULL_IMDCT flag on init.
|
||||
*/
|
||||
AV_TX_FLOAT_MDCT = 1,
|
||||
|
||||
@ -116,6 +117,14 @@ enum AVTXFlags {
|
||||
* May be slower with certain transform types.
|
||||
*/
|
||||
AV_TX_UNALIGNED = 1ULL << 1,
|
||||
|
||||
/**
|
||||
* Performs a full inverse MDCT rather than leaving out samples that can be
|
||||
* derived through symmetry. Requires an output array of 'len' floats,
|
||||
* rather than the usual 'len/2' floats.
|
||||
* Ignored for all transforms but inverse MDCTs.
|
||||
*/
|
||||
AV_TX_FULL_IMDCT = 1ULL << 2,
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -121,6 +121,10 @@ struct AVTXContext {
|
||||
int *pfatab; /* Input/Output mapping for compound transforms */
|
||||
int *revtab; /* Input mapping for power of two transforms */
|
||||
int *inplace_idx; /* Required indices to revtab for in-place transforms */
|
||||
|
||||
av_tx_fn top_tx; /* Used for computing transforms derived from other
|
||||
* transforms, like full-length iMDCTs and RDFTs.
|
||||
* NOTE: Do NOT use this to mix assembly with C code. */
|
||||
};
|
||||
|
||||
/* Checks if type is an MDCT */
|
||||
|
@ -875,6 +875,24 @@ static void naive_mdct(AVTXContext *s, void *_dst, void *_src,
|
||||
}
|
||||
}
|
||||
|
||||
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;
|
||||
@ -942,6 +960,10 @@ int TX_NAME(ff_tx_init_mdct_fft)(AVTXContext *s, av_tx_fn *tx,
|
||||
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;
|
||||
}
|
||||
@ -990,8 +1012,13 @@ int TX_NAME(ff_tx_init_mdct_fft)(AVTXContext *s, av_tx_fn *tx,
|
||||
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;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user