---
C: 30735
SSSE3: 9310
SSE4: 8400
AVX: 7652
x86 asm with 64-bit integer math is a huge PITA...
libavfilter/x86/af_volume.asm | 74 ++++++++++++++++++++++++++++++++++++++
libavfilter/x86/af_volume_init.c | 20 ++++++++++
2 files changed, 94 insertions(+), 0 deletions(-)
diff --git a/libavfilter/x86/af_volume.asm b/libavfilter/x86/af_volume.asm
index 602bab7..016fe8e 100644
--- a/libavfilter/x86/af_volume.asm
+++ b/libavfilter/x86/af_volume.asm
@@ -24,6 +24,10 @@
SECTION_RODATA 32
pd_128: times 4 dd 128
+pq_128: times 2 dq 128
+pq_minsq: times 2 dq -549755813888 ; INT_MIN << 8
+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 +59,73 @@ 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)
+;------------------------------------------------------------------------------
+
+%macro PMINSQ 3 ; dst, src, tmp
+ pcmpgtq %3, %2, %1
+ pxor %1, %2
+ pand %1, %3
+ pxor %1, %2
+%endmacro
+
+%macro PMAXSQ 3 ; dst, src, tmp
+ pcmpgtq %3, %1, %2
+ pand %1, %3
+ pandn %3, %2
+ por %1, %3
+%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_minsq]
+ mova m5, [pq_maxsq]
+ mova m6, [pb_packqd_rsh8]
+ lea lenq, [lend*4-mmsize]
+.loop:
+ ; src[i] = av_clipl_int32((src[i] * volume + 128) >> 8);
+ mova m1, [srcq+lenq]
+ mova m2, m1
+ punpckhdq m2, m1, m1
+ punpckldq m1, m1, m1
+%if cpuflag(sse4)
+ pmuldq m1, m0
+ pmuldq m2, m0
+%else ; ssse3
+ pabsd m1, m1
+ pabsd m2, m2
+ pmuludq m1, m0
+ pmuludq m2, m0
+%endif
+ paddq m1, m3
+ paddq m2, m3
+ PMINSQ m1, m5, m7
+ PMAXSQ m1, m4, m7
+ PMINSQ m2, m5, m7
+ PMAXSQ m2, m4, m7
+ pshufb m1, m6
+ pshufb m2, m6
+ punpcklqdq m1, m2
+%if notcpuflag(sse4) ; ssse3
+ psignd m1, [srcq+lenq]
+%endif
+ mova [srcq+lenq], m1
+ sub lenq, mmsize
+ jge .loop
+ REP_RET
+%endmacro
+
+INIT_XMM ssse3
+SCALE_SAMPLES_S32
+INIT_XMM sse4
+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..a71a6cd 100644
--- a/libavfilter/x86/af_volume_init.c
+++ b/libavfilter/x86/af_volume_init.c
@@ -24,6 +24,13 @@
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_sse4(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 +41,18 @@ 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_SSE4(mm_flags)) {
+ vol->scale_samples_int = ff_scale_samples_s32_sse4;
+ 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