---
 libavcodec/fmtconvert.c         |    8 ++++++++
 libavcodec/fmtconvert.h         |   11 +++++++++++
 libavcodec/x86/fmtconvert.asm   |   29 +++++++++++++++++++++++++++++
 libavcodec/x86/fmtconvert_mmx.c |    5 +++++
 4 files changed, 53 insertions(+)

diff --git a/libavcodec/fmtconvert.c b/libavcodec/fmtconvert.c
index 58fece7..4b683d2 100644
--- a/libavcodec/fmtconvert.c
+++ b/libavcodec/fmtconvert.c
@@ -29,6 +29,13 @@ static void int32_to_float_fmul_scalar_c(float *dst, const 
int *src, float mul,
         dst[i] = src[i] * mul;
 }
 
+static void int32_to_int16_clipped_c(int16_t *dst, const int32_t *src, int len)
+{
+    int i;
+    for (i = 0; i < len; i++)
+        dst[i] = av_clip_int16(src[i]);
+}
+
 static av_always_inline int float_to_int16_one(const float *src){
     return av_clip_int16(lrintf(*src));
 }
@@ -81,6 +88,7 @@ av_cold void ff_fmt_convert_init(FmtConvertContext *c, 
AVCodecContext *avctx)
     c->float_to_int16             = float_to_int16_c;
     c->float_to_int16_interleave  = float_to_int16_interleave_c;
     c->float_interleave           = ff_float_interleave_c;
+    c->int32_to_int16_clipped     = int32_to_int16_clipped_c;
 
     if (ARCH_ARM) ff_fmt_convert_init_arm(c, avctx);
     if (HAVE_ALTIVEC) ff_fmt_convert_init_altivec(c, avctx);
diff --git a/libavcodec/fmtconvert.h b/libavcodec/fmtconvert.h
index b879ee6..824f70b 100644
--- a/libavcodec/fmtconvert.h
+++ b/libavcodec/fmtconvert.h
@@ -38,6 +38,17 @@ typedef struct FmtConvertContext {
     void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, 
int len);
 
     /**
+     * Convert an array of int32_t to clipped int16_t.
+     * @param dst destination array of int16_t.
+     *            constraints: 16-byte aligned
+     * @param src source array of int32_t.
+     *            constraints: 16-byte aligned
+     * @param len number of elements to convert.
+     *            constraints: multiple of 8
+     */
+    void (*int32_to_int16_clipped)(int16_t *dst, const int32_t *src, int len);
+
+    /**
      * Convert an array of float to an array of int16_t.
      *
      * Convert floats from in the range [-32768.0,32767.0] to ints
diff --git a/libavcodec/x86/fmtconvert.asm b/libavcodec/x86/fmtconvert.asm
index 63befc9..05ce7c7 100644
--- a/libavcodec/x86/fmtconvert.asm
+++ b/libavcodec/x86/fmtconvert.asm
@@ -365,3 +365,32 @@ INIT_XMM
 %define PUNPCKLDQ unpcklps
 %define PUNPCKHDQ unpckhps
 FLOAT_INTERLEAVE2 sse, 5
+
+;-------------------------------------------------------------------------------
+; void ff_int32_to_int16_clipped(int16_t *dst, const int32_t *src, int len);
+;-------------------------------------------------------------------------------
+
+%macro INT32_TO_INT16_CLIPPED 0
+cglobal int32_to_int16_clipped, 3, 3, 1, dst, src, len
+    add     lenq, lenq
+    lea     srcq, [srcq + 2 * lenq]
+    add     dstq, lenq
+    neg     lenq
+
+.loop:
+    mova      m0, [srcq + 2 * lenq]
+    packssdw  m0, [srcq + 2 * lenq + mmsize]
+    mova      [dstq + lenq], m0
+    add     lenq, mmsize
+    jl .loop
+%if mmsize == 8
+    RET
+%else
+    REP_RET
+%endif
+%endmacro
+
+INIT_MMX mmx
+INT32_TO_INT16_CLIPPED
+INIT_XMM sse2
+INT32_TO_INT16_CLIPPED
diff --git a/libavcodec/x86/fmtconvert_mmx.c b/libavcodec/x86/fmtconvert_mmx.c
index 42cb0bc..87cd504 100644
--- a/libavcodec/x86/fmtconvert_mmx.c
+++ b/libavcodec/x86/fmtconvert_mmx.c
@@ -43,6 +43,9 @@ void ff_float_to_int16_interleave6_sse(int16_t *dst, const 
float **src, int len)
 void ff_float_to_int16_interleave6_3dnow(int16_t *dst, const float **src, int 
len);
 void ff_float_to_int16_interleave6_3dn2(int16_t *dst, const float **src, int 
len);
 
+void ff_int32_to_int16_clipped_mmx(int16_t *dst, const int32_t *src, int len);
+void ff_int32_to_int16_clipped_sse2(int16_t *dst, const int32_t *src, int len);
+
 #define ff_float_to_int16_interleave6_sse2 ff_float_to_int16_interleave6_sse
 
 #define FLOAT_TO_INT16_INTERLEAVE(cpu) \
@@ -115,6 +118,7 @@ void ff_fmt_convert_init_x86(FmtConvertContext *c, 
AVCodecContext *avctx)
 
     if (mm_flags & AV_CPU_FLAG_MMX) {
         c->float_interleave = float_interleave_mmx;
+        c->int32_to_int16_clipped = ff_int32_to_int16_clipped_mmx;
 
         if (HAVE_AMD3DNOW && mm_flags & AV_CPU_FLAG_3DNOW) {
             if(!(avctx->flags & CODEC_FLAG_BITEXACT)){
@@ -137,6 +141,7 @@ void ff_fmt_convert_init_x86(FmtConvertContext *c, 
AVCodecContext *avctx)
             c->int32_to_float_fmul_scalar = ff_int32_to_float_fmul_scalar_sse2;
             c->float_to_int16 = ff_float_to_int16_sse2;
             c->float_to_int16_interleave = float_to_int16_interleave_sse2;
+            c->int32_to_int16_clipped = ff_int32_to_int16_clipped_sse2;        
         }
     }
 #endif
-- 
1.7.10

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

Reply via email to