---
The previous patch was doing some unnecessary things in the SSSE3
version. Once I removed those, it was faster than the SSE4 version.
C: 30735
SSSE3: 6158
AVX: 5656
libavfilter/x86/af_volume.asm | 58 ++++++++++++++++++++++++++++++++++++++
libavfilter/x86/af_volume_init.c | 14 +++++++++
2 files changed, 72 insertions(+), 0 deletions(-)
diff --git a/libavfilter/x86/af_volume.asm b/libavfilter/x86/af_volume.asm
index 602bab7..4094676 100644
--- a/libavfilter/x86/af_volume.asm
+++ b/libavfilter/x86/af_volume.asm
@@ -24,6 +24,9 @@
SECTION_RODATA 32
pd_128: times 4 dd 128
+pq_128: times 2 dq 128
+pq_maxsq: times 2 dq 549755813632 ; INT_MAX << 8
+pb_packqd_rsh8: db 1, 2, 3, 4, 9, 10, 11, 12, -1, -1, -1, -1, -1, -1, -1, -1
SECTION_TEXT
@@ -55,3 +58,58 @@ cglobal scale_samples_s16, 4,4,4, ctx, src, len, volume
sub lenq, mmsize
jge .loop
REP_RET
+
+;------------------------------------------------------------------------------
+; void ff_scale_samples_s32(VolumeContext *ctx, uint8_t *src, int len,
+; int volume)
+;------------------------------------------------------------------------------
+
+; NOTE: This is not bit-identical with the C version because it clips to
+; [-INT_MAX, INT_MAX] instead of [INT_MIN, INT_MAX]
+
+%macro PMINSQ 3 ; dst, src, tmp
+ pcmpgtq %3, %2, %1
+ pxor %1, %2
+ pand %1, %3
+ pxor %1, %2
+%endmacro
+
+%macro SCALE_SAMPLES_S32 0
+cglobal scale_samples_s32, 4,4,8, ctx, src, len, volume
+ movd m0, volumed
+ pshufd m0, m0, 0
+ mova m3, [pq_128]
+ mova m4, [pq_maxsq]
+ mova m5, [pb_packqd_rsh8]
+ lea lenq, [lend*4-mmsize]
+.loop:
+ ; src[i] = av_clipl_int32((src[i] * volume + 128) >> 8);
+ mova m1, [srcq+lenq]
+ mova m6, m1
+ mova m2, m1
+ punpckhdq m2, m1, m1
+ punpckldq m1, m1, m1
+ pabsd m1, m1
+ pabsd m2, m2
+ pmuludq m1, m0
+ pmuludq m2, m0
+ paddq m1, m3
+ paddq m2, m3
+ PMINSQ m1, m4, m7
+ PMINSQ m2, m4, m7
+ pshufb m1, m5
+ pshufb m2, m5
+ punpcklqdq m1, m2
+ psignd m1, m6
+ mova [srcq+lenq], m1
+ sub lenq, mmsize
+ jge .loop
+ REP_RET
+%endmacro
+
+INIT_XMM ssse3
+SCALE_SAMPLES_S32
+%if HAVE_AVX_EXTERNAL
+INIT_XMM avx
+SCALE_SAMPLES_S32
+%endif
diff --git a/libavfilter/x86/af_volume_init.c b/libavfilter/x86/af_volume_init.c
index 4a6782b..992b752 100644
--- a/libavfilter/x86/af_volume_init.c
+++ b/libavfilter/x86/af_volume_init.c
@@ -24,6 +24,11 @@
void ff_scale_samples_s16_sse4(VolumeContext *ctx, uint8_t *src, int len,
int volume);
+void ff_scale_samples_s32_ssse3(VolumeContext *ctx, uint8_t *src, int len,
+ int volume);
+void ff_scale_samples_s32_avx(VolumeContext *ctx, uint8_t *src, int len,
+ int volume);
+
void ff_volume_init_x86(VolumeContext *vol)
{
int mm_flags = av_get_cpu_flags();
@@ -34,5 +39,14 @@ void ff_volume_init_x86(VolumeContext *vol)
vol->scale_samples_int = ff_scale_samples_s16_sse4;
vol->samples_align = 8;
}
+ } else if (sample_fmt == AV_SAMPLE_FMT_S32) {
+ if (EXTERNAL_SSSE3(mm_flags)) {
+ vol->scale_samples_int = ff_scale_samples_s32_ssse3;
+ vol->samples_align = 4;
+ }
+ if (EXTERNAL_AVX(mm_flags)) {
+ vol->scale_samples_int = ff_scale_samples_s32_avx;
+ vol->samples_align = 4;
+ }
}
}
--
1.7.1
_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel