diff options
author | Justin Ruggles <justin.ruggles@gmail.com> | 2011-03-11 16:45:01 -0500 |
---|---|---|
committer | Justin Ruggles <justin.ruggles@gmail.com> | 2011-03-14 08:45:31 -0400 |
commit | f1efbca5e914b28cd37cb1ea82d371acf3b96f61 (patch) | |
tree | a1464d5951e558f17e941c9f13d3548b733e6c03 /libavcodec/x86 | |
parent | 323e6fead07c75f418e4b60704a4f437bb3483b2 (diff) |
ac3enc: add SIMD-optimized shifting functions for use with the fixed-point AC3 encoder.
Diffstat (limited to 'libavcodec/x86')
-rw-r--r-- | libavcodec/x86/ac3dsp.asm | 45 | ||||
-rw-r--r-- | libavcodec/x86/ac3dsp_mmx.c | 12 |
2 files changed, 57 insertions, 0 deletions
diff --git a/libavcodec/x86/ac3dsp.asm b/libavcodec/x86/ac3dsp.asm index b1eeca9cd2..e281791b1e 100644 --- a/libavcodec/x86/ac3dsp.asm +++ b/libavcodec/x86/ac3dsp.asm @@ -133,3 +133,48 @@ INIT_XMM AC3_MAX_MSB_ABS_INT16 sse2, min_max %define ABS2 ABS2_SSSE3 AC3_MAX_MSB_ABS_INT16 ssse3, or_abs + +;----------------------------------------------------------------------------- +; macro used for ff_ac3_lshift_int16() and ff_ac3_rshift_int32() +;----------------------------------------------------------------------------- + +%macro AC3_SHIFT 4 ; l/r, 16/32, shift instruction, instruction set +cglobal ac3_%1shift_int%2_%4, 3,3,5, src, len, shift + movd m0, shiftd +.loop: + mova m1, [srcq ] + mova m2, [srcq+mmsize ] + mova m3, [srcq+mmsize*2] + mova m4, [srcq+mmsize*3] + %3 m1, m0 + %3 m2, m0 + %3 m3, m0 + %3 m4, m0 + mova [srcq ], m1 + mova [srcq+mmsize ], m2 + mova [srcq+mmsize*2], m3 + mova [srcq+mmsize*3], m4 + add srcq, mmsize*4 + sub lend, mmsize*32/%2 + ja .loop +.end: + REP_RET +%endmacro + +;----------------------------------------------------------------------------- +; void ff_ac3_lshift_int16(int16_t *src, unsigned int len, unsigned int shift) +;----------------------------------------------------------------------------- + +INIT_MMX +AC3_SHIFT l, 16, psllw, mmx +INIT_XMM +AC3_SHIFT l, 16, psllw, sse2 + +;----------------------------------------------------------------------------- +; void ff_ac3_rshift_int32(int32_t *src, unsigned int len, unsigned int shift) +;----------------------------------------------------------------------------- + +INIT_MMX +AC3_SHIFT r, 32, psrad, mmx +INIT_XMM +AC3_SHIFT r, 32, psrad, sse2 diff --git a/libavcodec/x86/ac3dsp_mmx.c b/libavcodec/x86/ac3dsp_mmx.c index d8af59ce8d..835b10696d 100644 --- a/libavcodec/x86/ac3dsp_mmx.c +++ b/libavcodec/x86/ac3dsp_mmx.c @@ -32,6 +32,12 @@ extern int ff_ac3_max_msb_abs_int16_mmxext(const int16_t *src, int len); extern int ff_ac3_max_msb_abs_int16_sse2 (const int16_t *src, int len); extern int ff_ac3_max_msb_abs_int16_ssse3 (const int16_t *src, int len); +extern void ff_ac3_lshift_int16_mmx (int16_t *src, unsigned int len, unsigned int shift); +extern void ff_ac3_lshift_int16_sse2(int16_t *src, unsigned int len, unsigned int shift); + +extern void ff_ac3_rshift_int32_mmx (int32_t *src, unsigned int len, unsigned int shift); +extern void ff_ac3_rshift_int32_sse2(int32_t *src, unsigned int len, unsigned int shift); + av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c) { int mm_flags = av_get_cpu_flags(); @@ -40,6 +46,8 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c) if (mm_flags & AV_CPU_FLAG_MMX) { c->ac3_exponent_min = ff_ac3_exponent_min_mmx; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_mmx; + c->ac3_lshift_int16 = ff_ac3_lshift_int16_mmx; + c->ac3_rshift_int32 = ff_ac3_rshift_int32_mmx; } if (mm_flags & AV_CPU_FLAG_MMX2 && HAVE_MMX2) { c->ac3_exponent_min = ff_ac3_exponent_min_mmxext; @@ -48,6 +56,10 @@ av_cold void ff_ac3dsp_init_x86(AC3DSPContext *c) if (mm_flags & AV_CPU_FLAG_SSE2 && HAVE_SSE) { c->ac3_exponent_min = ff_ac3_exponent_min_sse2; c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_sse2; + if (!(mm_flags & AV_CPU_FLAG_SSE2SLOW)) { + c->ac3_lshift_int16 = ff_ac3_lshift_int16_sse2; + c->ac3_rshift_int32 = ff_ac3_rshift_int32_sse2; + } } if (mm_flags & AV_CPU_FLAG_SSSE3 && HAVE_SSSE3) { c->ac3_max_msb_abs_int16 = ff_ac3_max_msb_abs_int16_ssse3; |