[FFmpeg-devel] [PATCH 03/12] Add vector_clipf_interleave() function to dsputil

Mans Rullgard mans
Sun Sep 27 12:49:19 CEST 2009


---
 libavcodec/dsputil.c |   45 +++++++++++++++++++++++++++++++++++++++++++++
 libavcodec/dsputil.h |    3 +++
 2 files changed, 48 insertions(+), 0 deletions(-)

diff --git a/libavcodec/dsputil.c b/libavcodec/dsputil.c
index 2ffb1ba..ab916b7 100644
--- a/libavcodec/dsputil.c
+++ b/libavcodec/dsputil.c
@@ -4229,6 +4229,50 @@ static void vector_clipf_c(float *dst, const float *src, float min, float max, i
     }
 }
 
+static void vector_clipf_interleave_c_diff_sign(float *dst, const float **src,
+                                                float *min, float *max,
+                                                int len, int channels)
+{
+    int i, j, c;
+    uint32_t mini = *(uint32_t*)min;
+    uint32_t maxi = *(uint32_t*)max;
+    uint32_t maxisign = maxi ^ (1<<31);
+    uint32_t *dsti = (uint32_t*)dst;
+    const uint32_t **srci = (const uint32_t **)src;
+    if (channels == 2) {
+        for(i = 0; i < len; i++){
+            dsti[2*i  ] = clipf_c_one(srci[0][i], mini, maxi, maxisign);
+            dsti[2*i+1] = clipf_c_one(srci[1][i], mini, maxi, maxisign);
+        }
+    } else {
+        for (c = 0; c < channels; c++)
+            for (i = 0, j = c; i < len; i++, j += channels)
+                dsti[j] = clipf_c_one(srci[c][i], mini, maxi, maxisign);
+    }
+}
+
+static void vector_clipf_interleave_c(float *dst, const float **src,
+                                      float min, float max, int len,
+                                      int channels)
+{
+    int i, j, c;
+    if (channels == 1) {
+        vector_clipf_c(dst, src[0], min, max, len);
+    } else if (min < 0 && max > 0) {
+        vector_clipf_interleave_c_diff_sign(dst, src, &min, &max,
+                                            len, channels);
+    } else if (channels == 2) {
+        for(i = 0; i < len; i++){
+            dst[2*i  ] = av_clipf(src[0][i], min, max);
+            dst[2*i+1] = av_clipf(src[1][i], min, max);
+        }
+    } else {
+        for (c = 0; c < channels; c++)
+            for (i = 0, j = c; i < len; i++, j += channels)
+                dst[j] = av_clipf(src[c][i], min, max);
+    }
+}
+
 static av_always_inline int float_to_int16_one(const float *src){
     int_fast32_t tmp = *(const int32_t*)src;
     if(tmp & 0xf0000){
@@ -4807,6 +4851,7 @@ void dsputil_init(DSPContext* c, AVCodecContext *avctx)
     c->vector_fmul_window = ff_vector_fmul_window_c;
     c->int32_to_float_fmul_scalar = int32_to_float_fmul_scalar_c;
     c->vector_clipf = vector_clipf_c;
+    c->vector_clipf_interleave = vector_clipf_interleave_c;
     c->float_to_int16 = ff_float_to_int16_c;
     c->float_to_int16_interleave = ff_float_to_int16_interleave_c;
     c->add_int16 = add_int16_c;
diff --git a/libavcodec/dsputil.h b/libavcodec/dsputil.h
index 8af06ff..86ea1d0 100644
--- a/libavcodec/dsputil.h
+++ b/libavcodec/dsputil.h
@@ -399,6 +399,9 @@ typedef struct DSPContext {
                                     int step, int len);
     void (*int32_to_float_fmul_scalar)(float *dst, const int *src, float mul, int len);
     void (*vector_clipf)(float *dst /* align 16 */, const float *src /* align 16 */, float min, float max, int len /* align 16 */);
+    void (*vector_clipf_interleave)(float *dst, const float **src,
+                                    float min, float max, int len,
+                                    int channels);
     /**
      * Multiply a vector of floats by a scalar float.  Source and
      * destination vectors must overlap exactly or not at all.
-- 
1.6.4.4




More information about the ffmpeg-devel mailing list