[FFmpeg-devel] [PATCH] Separate window function from autocorrelation.
Måns Rullgård
mans
Wed Jan 19 21:12:15 CET 2011
Justin Ruggles <justin.ruggles at gmail.com> writes:
> This will allow the use of different window functions and also removes
> variable-length arrays in autocorrelation functions.
> ---
> libavcodec/dsputil.c | 1 +
> libavcodec/dsputil.h | 7 ++++++-
> libavcodec/lpc.c | 30 ++++++++++++++----------------
> libavcodec/lpc.h | 4 +++-
> libavcodec/x86/dsputil_mmx.h | 3 ++-
> libavcodec/x86/dsputilenc_mmx.c | 1 +
> libavcodec/x86/lpc_mmx.c | 20 ++++++--------------
> 7 files changed, 33 insertions(+), 33 deletions(-)
>
>
> diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
> index cc60524..3b2d421 100644
> --- a/libavcodec/dsputil.c
> +++ b/libavcodec/dsputil.c
> @@ -4432,6 +4432,7 @@ av_cold void dsputil_init(DSPContext* c, AVCodecContext *avctx)
> c->ac3_downmix = ff_ac3_downmix_c;
> #endif
> #if CONFIG_LPC
> + c->lpc_apply_welch_window = ff_lpc_apply_welch_window;
> c->lpc_compute_autocorr = ff_lpc_compute_autocorr;
> #endif
Maybe we should move the LPC functions out of DSPContext. This is as
good a time as any to do that.
> c->vector_fmul = vector_fmul_c;
> diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
> index 1571491..ad61188 100644
> --- a/libavcodec/dsputil.h
> +++ b/libavcodec/dsputil.h
> @@ -376,7 +376,12 @@ typedef struct DSPContext {
> void (*vorbis_inverse_coupling)(float *mag, float *ang, int blocksize);
> void (*ac3_downmix)(float (*samples)[256], float (*matrix)[2], int out_ch, int in_ch, int len);
> /* no alignment needed */
> - void (*lpc_compute_autocorr)(const int32_t *data, int len, int lag, double *autoc);
> + void (*lpc_apply_welch_window)(const int32_t *data, int len, double *w_data);
> + /* no alignment needed.
> + data must have have at least lag*sizeof(double) valid bytes preceeding it.
> + data must be at least (len+1)*sizeof(double) in length if data is
> + 16-byte aligned or (len+2)*sizeof(double) if data is unaligned. */
> + void (*lpc_compute_autocorr)(const double *data, int len, int lag, double *autoc);
A brief doxygen description of the function would be nice.
> @@ -179,12 +170,19 @@ int ff_lpc_calc_coefs(DSPContext *s,
> lpc_type > AV_LPC_TYPE_FIXED);
>
> if (lpc_type == AV_LPC_TYPE_LEVINSON) {
> - s->lpc_compute_autocorr(samples, blocksize, max_order, autoc);
> + double *ws = av_mallocz((blocksize + max_order + 2) * sizeof(double));
Unchecked malloc. Is it feasible to have this buffer allocate once
per codec instance instead of for each call?
> + double *windowed_samples = ws + max_order;
> +
> + s->lpc_apply_welch_window(samples, blocksize, windowed_samples);
> +
> + s->lpc_compute_autocorr(windowed_samples, blocksize, max_order, autoc);
>
> compute_lpc_coefs(autoc, max_order, &lpc[0][0], MAX_LPC_ORDER, 0, 1);
>
> for(i=0; i<max_order; i++)
> ref[i] = fabs(lpc[i][i]);
> +
> + av_freep(&ws);
> } else if (lpc_type == AV_LPC_TYPE_CHOLESKY) {
> LLSModel m[2];
> double var[MAX_LPC_ORDER+1], av_uninit(weight);
> diff --git a/libavcodec/lpc.h b/libavcodec/lpc.h
> index 1c595f6..4673fc4 100644
> --- a/libavcodec/lpc.h
> +++ b/libavcodec/lpc.h
> @@ -46,7 +46,9 @@ int ff_lpc_calc_coefs(DSPContext *s,
> enum AVLPCType lpc_type, int lpc_passes,
> int omethod, int max_shift, int zero_shift);
>
> -void ff_lpc_compute_autocorr(const int32_t *data, int len, int lag,
> +void ff_lpc_apply_welch_window(const int32_t *data, int len, double *w_data);
> +
> +void ff_lpc_compute_autocorr(const double *data, int len, int lag,
> double *autoc);
>
> #ifdef LPC_USE_DOUBLE
> diff --git a/libavcodec/x86/dsputil_mmx.h b/libavcodec/x86/dsputil_mmx.h
> index c57bbbf..52cd810 100644
> --- a/libavcodec/x86/dsputil_mmx.h
> +++ b/libavcodec/x86/dsputil_mmx.h
> @@ -200,7 +200,8 @@ void ff_vc1dsp_init_mmx(DSPContext* dsp, AVCodecContext *avctx);
> void ff_put_vc1_mspel_mc00_mmx(uint8_t *dst, const uint8_t *src, int stride, int rnd);
> void ff_avg_vc1_mspel_mc00_mmx2(uint8_t *dst, const uint8_t *src, int stride, int rnd);
>
> -void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag,
> +void ff_lpc_apply_welch_window_sse2(const int32_t *data, int len, double *w_data);
> +void ff_lpc_compute_autocorr_sse2(const double *data, int len, int lag,
> double *autoc);
>
> void ff_mmx_idct(DCTELEM *block);
> diff --git a/libavcodec/x86/dsputilenc_mmx.c b/libavcodec/x86/dsputilenc_mmx.c
> index f02d1ca..18a10c8 100644
> --- a/libavcodec/x86/dsputilenc_mmx.c
> +++ b/libavcodec/x86/dsputilenc_mmx.c
> @@ -1167,6 +1167,7 @@ void dsputilenc_init_mmx(DSPContext* c, AVCodecContext *avctx)
> }
>
> if (CONFIG_LPC && mm_flags & (AV_CPU_FLAG_SSE2|AV_CPU_FLAG_SSE2SLOW)) {
> + c->lpc_apply_welch_window = ff_lpc_apply_welch_window_sse2;
> c->lpc_compute_autocorr = ff_lpc_compute_autocorr_sse2;
> }
>
> diff --git a/libavcodec/x86/lpc_mmx.c b/libavcodec/x86/lpc_mmx.c
> index 49eb569..3e740c6 100644
> --- a/libavcodec/x86/lpc_mmx.c
> +++ b/libavcodec/x86/lpc_mmx.c
> @@ -22,7 +22,7 @@
> #include "libavutil/x86_cpu.h"
> #include "dsputil_mmx.h"
>
> -static void apply_welch_window_sse2(const int32_t *data, int len, double *w_data)
> +void ff_lpc_apply_welch_window_sse2(const int32_t *data, int len, double *w_data)
> {
> double c = 2.0 / (len-1.0);
> int n2 = len>>1;
> @@ -68,21 +68,13 @@ static void apply_welch_window_sse2(const int32_t *data, int len, double *w_data
> #undef WELCH
> }
>
> -void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag,
> +void ff_lpc_compute_autocorr_sse2(const double *data, int len, int lag,
> double *autoc)
> {
> - double tmp[len + lag + 2];
> - double *data1 = tmp + lag;
> int j;
>
> - if((x86_reg)data1 & 15)
> - data1++;
> -
> - apply_welch_window_sse2(data, len, data1);
> -
> - for(j=0; j<lag; j++)
> - data1[j-lag]= 0.0;
> - data1[len] = 0.0;
> + if((x86_reg)data & 15)
> + data++;
>
> for(j=0; j<lag; j+=2){
> x86_reg i = -len*sizeof(double);
> @@ -113,7 +105,7 @@ void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag,
> "movsd %%xmm1, 8(%1) \n\t"
> "movsd %%xmm2, 16(%1) \n\t"
> :"+&r"(i)
> - :"r"(autoc+j), "r"(data1+len), "r"(data1+len-j)
> + :"r"(autoc+j), "r"(data+len), "r"(data+len-j)
> :"memory"
> );
> } else {
> @@ -136,7 +128,7 @@ void ff_lpc_compute_autocorr_sse2(const int32_t *data, int len, int lag,
> "movsd %%xmm0, %1 \n\t"
> "movsd %%xmm1, %2 \n\t"
> :"+&r"(i), "=m"(autoc[j]), "=m"(autoc[j+1])
> - :"r"(data1+len), "r"(data1+len-j)
> + :"r"(data+len), "r"(data+len-j)
> );
> }
> }
The rest looks good.
--
M?ns Rullg?rd
mans at mansr.com
More information about the ffmpeg-devel
mailing list