---
 libavresample/dither.c          |    3 +
 libavresample/dither.h          |    5 ++
 libavresample/x86/Makefile      |    2 +
 libavresample/x86/dither.asm    |   79 +++++++++++++++++++++++++++++++++++++++
 libavresample/x86/dither_init.c |   67 +++++++++++++++++++++++++++++++++
 5 files changed, 156 insertions(+), 0 deletions(-)
 create mode 100644 libavresample/x86/dither.asm
 create mode 100644 libavresample/x86/dither_init.c

diff --git a/libavresample/dither.c b/libavresample/dither.c
index c00cb16..10bdc19 100644
--- a/libavresample/dither.c
+++ b/libavresample/dither.c
@@ -356,6 +356,9 @@ static void dither_init(DitherDSPContext *ddsp,
     }
     ddsp->ptr_align     = 1;
     ddsp->samples_align = 1;
+
+    if (ARCH_X86)
+        ff_dither_init_x86(ddsp, method);
 }
 
 DitherContext *ff_dither_alloc(AVAudioResampleContext *avr,
diff --git a/libavresample/dither.h b/libavresample/dither.h
index 38a0c76..eb7006e 100644
--- a/libavresample/dither.h
+++ b/libavresample/dither.h
@@ -86,4 +86,9 @@ void ff_dither_free(DitherContext **c);
  */
 int ff_convert_dither(DitherContext *c, AudioData *dst, AudioData *src);
 
+/* arch-specific initialization functions */
+
+void ff_dither_init_x86(DitherDSPContext *ddsp,
+                        enum AVResampleDitherMethod method);
+
 #endif /* AVRESAMPLE_DITHER_H */
diff --git a/libavresample/x86/Makefile b/libavresample/x86/Makefile
index 65bed89..2e8786f 100644
--- a/libavresample/x86/Makefile
+++ b/libavresample/x86/Makefile
@@ -1,5 +1,7 @@
 OBJS      += x86/audio_convert_init.o                                   \
              x86/audio_mix_init.o                                       \
+             x86/dither_init.o                                          \
 
 YASM-OBJS += x86/audio_convert.o                                        \
              x86/audio_mix.o                                            \
+             x86/dither.o                                               \
diff --git a/libavresample/x86/dither.asm b/libavresample/x86/dither.asm
new file mode 100644
index 0000000..821a9ef
--- /dev/null
+++ b/libavresample/x86/dither.asm
@@ -0,0 +1,79 @@
+;******************************************************************************
+;* x86 optimized dithering format conversion
+;* Copyright (c) 2012 Justin Ruggles <[email protected]>
+;*
+;* 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 "libavutil/x86/x86util.asm"
+
+SECTION_RODATA 32
+
+; 1.0f / (2.0f * INT32_MAX)
+pf_dither_scale: times 8 dd 2.32830643762e-10
+
+pf_s16_scale: times 4 dd 32753.0
+
+SECTION_TEXT
+
+;------------------------------------------------------------------------------
+; void ff_quantize_int_rectangular/triangular(int16_t *dst, float *src,
+;                                             int *dither, int len);
+;------------------------------------------------------------------------------
+
+%macro QUANTIZE_INT 1
+cglobal quantize_int_%1, 4,5,6, dst, src, dither0, len, dither1
+    lea         lenq, [2*lend]
+    add         dstq, lenq
+    lea         srcq, [srcq+2*lenq]
+%ifidn %1, triangular
+    lea     dither1q, [dither0q+4*lenq]
+%endif
+    lea     dither0q, [dither0q+2*lenq]
+    neg         lenq
+    mova          m4, [pf_dither_scale]
+    mova          m5, [pf_s16_scale]
+.loop:
+    cvtdq2ps      m0, [dither0q+2*lenq]
+    cvtdq2ps      m1, [dither0q+2*lenq+mmsize]
+%ifidn %1, triangular
+    cvtdq2ps      m2, [dither1q+2*lenq]
+    cvtdq2ps      m3, [dither1q+2*lenq+mmsize]
+    addps         m0, m2
+    addps         m1, m3
+%endif
+    mulps         m2, m5, [srcq+2*lenq]
+    mulps         m3, m5, [srcq+2*lenq+mmsize]
+    fmaddps       m0, m0, m4, m2, m3
+    fmaddps       m1, m1, m4, m3, m2
+    cvtps2dq      m0, m0
+    cvtps2dq      m1, m1
+    packssdw      m0, m1
+    mova     [dstq+lenq], m0
+    add         lenq, mmsize
+    jl .loop
+    REP_RET
+%endmacro
+
+INIT_XMM sse2
+QUANTIZE_INT rectangular
+QUANTIZE_INT triangular
+%if HAVE_FMA4_EXTERNAL
+INIT_XMM fma4
+QUANTIZE_INT rectangular
+QUANTIZE_INT triangular
+%endif
diff --git a/libavresample/x86/dither_init.c b/libavresample/x86/dither_init.c
new file mode 100644
index 0000000..35a74a0
--- /dev/null
+++ b/libavresample/x86/dither_init.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2012 Justin Ruggles <[email protected]>
+ *
+ * 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 "libavutil/cpu.h"
+#include "libavutil/x86/cpu.h"
+#include "libavresample/dither.h"
+
+extern void ff_quantize_int_rectangular_sse2(int16_t *dst, const float *src,
+                                             void *dither, int len);
+extern void ff_quantize_int_rectangular_fma4(int16_t *dst, const float *src,
+                                             void *dither, int len);
+
+extern void ff_quantize_int_triangular_sse2(int16_t *dst, const float *src,
+                                            void *dither, int len);
+extern void ff_quantize_int_triangular_fma4(int16_t *dst, const float *src,
+                                            void *dither, int len);
+
+av_cold void ff_dither_init_x86(DitherDSPContext *ddsp,
+                                enum AVResampleDitherMethod method)
+{
+    int mm_flags = av_get_cpu_flags();
+
+    switch (method) {
+    case AV_RESAMPLE_DITHER_RECTANGULAR:
+        if (EXTERNAL_SSE2(mm_flags)) {
+            ddsp->quantize      = ff_quantize_int_rectangular_sse2;
+            ddsp->ptr_align     = 16;
+            ddsp->samples_align = 8;
+        }
+        if (EXTERNAL_FMA4(mm_flags)) {
+            ddsp->quantize      = ff_quantize_int_rectangular_fma4;
+            ddsp->ptr_align     = 16;
+            ddsp->samples_align = 8;
+        }
+        break;
+    case AV_RESAMPLE_DITHER_TRIANGULAR:
+        if (EXTERNAL_SSE2(mm_flags)) {
+            ddsp->quantize      = ff_quantize_int_triangular_sse2;
+            ddsp->ptr_align     = 16;
+            ddsp->samples_align = 8;
+        }
+        if (EXTERNAL_FMA4(mm_flags)) {
+            ddsp->quantize      = ff_quantize_int_triangular_fma4;
+            ddsp->ptr_align     = 16;
+            ddsp->samples_align = 8;
+        }
+        break;
+    }
+}
-- 
1.7.1

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to