mirror of https://github.com/FFmpeg/FFmpeg.git
This separation allows these functions to be used in a cleaner fashion from other codecs (e.g. qdm2) and simplifies creating optimised versions of them. Signed-off-by: Mans Rullgard <mans@mansr.com>pull/2/head
parent
ea91e77127
commit
c4f5c2d6f4
17 changed files with 390 additions and 255 deletions
@ -0,0 +1,40 @@ |
||||
/*
|
||||
* Copyright (c) 2011 Mans Rullgard |
||||
* |
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include "config.h" |
||||
#include "mpegaudiodsp.h" |
||||
#include "dct.h" |
||||
#include "dct32.h" |
||||
|
||||
void ff_mpadsp_init(MPADSPContext *s) |
||||
{ |
||||
DCTContext dct; |
||||
|
||||
ff_dct_init(&dct, 5, DCT_II); |
||||
|
||||
s->apply_window_float = ff_mpadsp_apply_window_float; |
||||
s->apply_window_fixed = ff_mpadsp_apply_window_fixed; |
||||
|
||||
s->dct32_float = dct.dct32; |
||||
s->dct32_fixed = ff_dct32_fixed; |
||||
|
||||
if (HAVE_MMX) ff_mpadsp_init_mmx(s); |
||||
if (HAVE_ALTIVEC) ff_mpadsp_init_altivec(s); |
||||
} |
@ -0,0 +1,63 @@ |
||||
/*
|
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef AVCODEC_MPEGAUDIODSP_H |
||||
#define AVCODEC_MPEGAUDIODSP_H |
||||
|
||||
#include <stdint.h> |
||||
|
||||
typedef struct MPADSPContext { |
||||
void (*apply_window_float)(float *synth_buf, float *window, |
||||
int *dither_state, float *samples, int incr); |
||||
void (*apply_window_fixed)(int32_t *synth_buf, int32_t *window, |
||||
int *dither_state, int16_t *samples, int incr); |
||||
void (*dct32_float)(float *dst, const float *src); |
||||
void (*dct32_fixed)(int *dst, const int *src); |
||||
} MPADSPContext; |
||||
|
||||
void ff_mpadsp_init(MPADSPContext *s); |
||||
|
||||
extern int32_t ff_mpa_synth_window_fixed[]; |
||||
extern float ff_mpa_synth_window_float[]; |
||||
|
||||
void ff_mpa_synth_filter_fixed(MPADSPContext *s, |
||||
int32_t *synth_buf_ptr, int *synth_buf_offset, |
||||
int32_t *window, int *dither_state, |
||||
int16_t *samples, int incr, |
||||
int *sb_samples); |
||||
|
||||
void ff_mpa_synth_filter_float(MPADSPContext *s, |
||||
float *synth_buf_ptr, int *synth_buf_offset, |
||||
float *window, int *dither_state, |
||||
float *samples, int incr, |
||||
float *sb_samples); |
||||
|
||||
void ff_mpadsp_init_mmx(MPADSPContext *s); |
||||
void ff_mpadsp_init_altivec(MPADSPContext *s); |
||||
|
||||
void ff_mpa_synth_init_float(float *window); |
||||
void ff_mpa_synth_init_fixed(int32_t *window); |
||||
|
||||
void ff_mpadsp_apply_window_float(float *synth_buf, float *window, |
||||
int *dither_state, float *samples, |
||||
int incr); |
||||
void ff_mpadsp_apply_window_fixed(int32_t *synth_buf, int32_t *window, |
||||
int *dither_state, int16_t *samples, |
||||
int incr); |
||||
|
||||
#endif |
@ -0,0 +1,20 @@ |
||||
/*
|
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#define CONFIG_FLOAT 0 |
||||
#include "mpegaudiodsp_template.c" |
@ -0,0 +1,20 @@ |
||||
/*
|
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#define CONFIG_FLOAT 1 |
||||
#include "mpegaudiodsp_template.c" |
@ -0,0 +1,205 @@ |
||||
/*
|
||||
* Copyright (c) 2001, 2002 Fabrice Bellard |
||||
* |
||||
* This file is part of Libav. |
||||
* |
||||
* Libav is free software; you can redistribute it and/or |
||||
* modify it under the terms of the GNU Lesser General Public |
||||
* License as published by the Free Software Foundation; either |
||||
* version 2.1 of the License, or (at your option) any later version. |
||||
* |
||||
* Libav is distributed in the hope that it will be useful, |
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
||||
* Lesser General Public License for more details. |
||||
* |
||||
* You should have received a copy of the GNU Lesser General Public |
||||
* License along with Libav; if not, write to the Free Software |
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#include <stdint.h> |
||||
|
||||
#include "libavutil/mem.h" |
||||
#include "dct32.h" |
||||
#include "mathops.h" |
||||
#include "mpegaudiodsp.h" |
||||
#include "mpegaudio.h" |
||||
#include "mpegaudiodata.h" |
||||
|
||||
#if CONFIG_FLOAT |
||||
#define RENAME(n) n##_float |
||||
|
||||
static inline float round_sample(float *sum) |
||||
{ |
||||
float sum1=*sum; |
||||
*sum = 0; |
||||
return sum1; |
||||
} |
||||
|
||||
#define MACS(rt, ra, rb) rt+=(ra)*(rb) |
||||
#define MULS(ra, rb) ((ra)*(rb)) |
||||
#define MLSS(rt, ra, rb) rt-=(ra)*(rb) |
||||
|
||||
#else |
||||
|
||||
#define RENAME(n) n##_fixed |
||||
#define OUT_SHIFT (WFRAC_BITS + FRAC_BITS - 15) |
||||
|
||||
static inline int round_sample(int64_t *sum) |
||||
{ |
||||
int sum1; |
||||
sum1 = (int)((*sum) >> OUT_SHIFT); |
||||
*sum &= (1<<OUT_SHIFT)-1; |
||||
return av_clip_int16(sum1); |
||||
} |
||||
|
||||
# define MULS(ra, rb) MUL64(ra, rb) |
||||
# define MACS(rt, ra, rb) MAC64(rt, ra, rb) |
||||
# define MLSS(rt, ra, rb) MLS64(rt, ra, rb) |
||||
#endif |
||||
|
||||
DECLARE_ALIGNED(16, MPA_INT, RENAME(ff_mpa_synth_window))[512+256]; |
||||
|
||||
#define SUM8(op, sum, w, p) \ |
||||
{ \
|
||||
op(sum, (w)[0 * 64], (p)[0 * 64]); \
|
||||
op(sum, (w)[1 * 64], (p)[1 * 64]); \
|
||||
op(sum, (w)[2 * 64], (p)[2 * 64]); \
|
||||
op(sum, (w)[3 * 64], (p)[3 * 64]); \
|
||||
op(sum, (w)[4 * 64], (p)[4 * 64]); \
|
||||
op(sum, (w)[5 * 64], (p)[5 * 64]); \
|
||||
op(sum, (w)[6 * 64], (p)[6 * 64]); \
|
||||
op(sum, (w)[7 * 64], (p)[7 * 64]); \
|
||||
} |
||||
|
||||
#define SUM8P2(sum1, op1, sum2, op2, w1, w2, p) \ |
||||
{ \
|
||||
INTFLOAT tmp;\
|
||||
tmp = p[0 * 64];\
|
||||
op1(sum1, (w1)[0 * 64], tmp);\
|
||||
op2(sum2, (w2)[0 * 64], tmp);\
|
||||
tmp = p[1 * 64];\
|
||||
op1(sum1, (w1)[1 * 64], tmp);\
|
||||
op2(sum2, (w2)[1 * 64], tmp);\
|
||||
tmp = p[2 * 64];\
|
||||
op1(sum1, (w1)[2 * 64], tmp);\
|
||||
op2(sum2, (w2)[2 * 64], tmp);\
|
||||
tmp = p[3 * 64];\
|
||||
op1(sum1, (w1)[3 * 64], tmp);\
|
||||
op2(sum2, (w2)[3 * 64], tmp);\
|
||||
tmp = p[4 * 64];\
|
||||
op1(sum1, (w1)[4 * 64], tmp);\
|
||||
op2(sum2, (w2)[4 * 64], tmp);\
|
||||
tmp = p[5 * 64];\
|
||||
op1(sum1, (w1)[5 * 64], tmp);\
|
||||
op2(sum2, (w2)[5 * 64], tmp);\
|
||||
tmp = p[6 * 64];\
|
||||
op1(sum1, (w1)[6 * 64], tmp);\
|
||||
op2(sum2, (w2)[6 * 64], tmp);\
|
||||
tmp = p[7 * 64];\
|
||||
op1(sum1, (w1)[7 * 64], tmp);\
|
||||
op2(sum2, (w2)[7 * 64], tmp);\
|
||||
} |
||||
|
||||
void RENAME(ff_mpadsp_apply_window)(MPA_INT *synth_buf, MPA_INT *window, |
||||
int *dither_state, OUT_INT *samples, |
||||
int incr) |
||||
{ |
||||
register const MPA_INT *w, *w2, *p; |
||||
int j; |
||||
OUT_INT *samples2; |
||||
#if CONFIG_FLOAT |
||||
float sum, sum2; |
||||
#else |
||||
int64_t sum, sum2; |
||||
#endif |
||||
|
||||
/* copy to avoid wrap */ |
||||
memcpy(synth_buf + 512, synth_buf, 32 * sizeof(*synth_buf)); |
||||
|
||||
samples2 = samples + 31 * incr; |
||||
w = window; |
||||
w2 = window + 31; |
||||
|
||||
sum = *dither_state; |
||||
p = synth_buf + 16; |
||||
SUM8(MACS, sum, w, p); |
||||
p = synth_buf + 48; |
||||
SUM8(MLSS, sum, w + 32, p); |
||||
*samples = round_sample(&sum); |
||||
samples += incr; |
||||
w++; |
||||
|
||||
/* we calculate two samples at the same time to avoid one memory
|
||||
access per two sample */ |
||||
for(j=1;j<16;j++) { |
||||
sum2 = 0; |
||||
p = synth_buf + 16 + j; |
||||
SUM8P2(sum, MACS, sum2, MLSS, w, w2, p); |
||||
p = synth_buf + 48 - j; |
||||
SUM8P2(sum, MLSS, sum2, MLSS, w + 32, w2 + 32, p); |
||||
|
||||
*samples = round_sample(&sum); |
||||
samples += incr; |
||||
sum += sum2; |
||||
*samples2 = round_sample(&sum); |
||||
samples2 -= incr; |
||||
w++; |
||||
w2--; |
||||
} |
||||
|
||||
p = synth_buf + 32; |
||||
SUM8(MLSS, sum, w + 32, p); |
||||
*samples = round_sample(&sum); |
||||
*dither_state= sum; |
||||
} |
||||
|
||||
/* 32 sub band synthesis filter. Input: 32 sub band samples, Output:
|
||||
32 samples. */ |
||||
void RENAME(ff_mpa_synth_filter)(MPADSPContext *s, MPA_INT *synth_buf_ptr, |
||||
int *synth_buf_offset, |
||||
MPA_INT *window, int *dither_state, |
||||
OUT_INT *samples, int incr, |
||||
MPA_INT *sb_samples) |
||||
{ |
||||
MPA_INT *synth_buf; |
||||
int offset; |
||||
|
||||
offset = *synth_buf_offset; |
||||
synth_buf = synth_buf_ptr + offset; |
||||
|
||||
s->RENAME(dct32)(synth_buf, sb_samples); |
||||
s->RENAME(apply_window)(synth_buf, window, dither_state, samples, incr); |
||||
|
||||
offset = (offset - 32) & 511; |
||||
*synth_buf_offset = offset; |
||||
} |
||||
|
||||
void av_cold RENAME(ff_mpa_synth_init)(MPA_INT *window) |
||||
{ |
||||
int i, j; |
||||
|
||||
/* max = 18760, max sum over all 16 coefs : 44736 */ |
||||
for(i=0;i<257;i++) { |
||||
INTFLOAT v; |
||||
v = ff_mpa_enwindow[i]; |
||||
#if CONFIG_FLOAT |
||||
v *= 1.0 / (1LL<<(16 + FRAC_BITS)); |
||||
#endif |
||||
window[i] = v; |
||||
if ((i & 63) != 0) |
||||
v = -v; |
||||
if (i != 0) |
||||
window[512 - i] = v; |
||||
} |
||||
|
||||
// Needed for avoiding shuffles in ASM implementations
|
||||
for(i=0; i < 8; i++) |
||||
for(j=0; j < 16; j++) |
||||
window[512+16*i+j] = window[64*i+32-j]; |
||||
|
||||
for(i=0; i < 8; i++) |
||||
for(j=0; j < 16; j++) |
||||
window[512+128+16*i+j] = window[64*i+48-j]; |
||||
} |
Loading…
Reference in new issue