[FFmpeg-devel] [RFC/PATCH] More flexible variafloat_to_int16 , WMA optimization, Vorbis

Loren Merritt lorenm
Tue Jul 15 09:57:33 CEST 2008


On Tue, 15 Jul 2008, Siarhei Siamashka wrote:
>
> Regarding, "float_to_int16_interleave" function, it would be nice to also
> add at least "stride" argument in addition to "len". That would make it usable
> for WMA. And it could be still possibly useful for vorbis (with some changes
> to code, stride might become needed).

like this? (wma part not really tested)

--Loren Merritt
-------------- next part --------------
Index: dsputil.c
===================================================================
--- dsputil.c	(revision 14207)
+++ dsputil.c	(working copy)
@@ -3962,15 +3962,15 @@
         dst[i] = float_to_int16_one(src+i);
 }
 
-void ff_float_to_int16_interleave_c(int16_t *dst, const float *src, long len, int channels){
+void ff_float_to_int16_interleave_c(int16_t *dst, const float *src, long len, long stride, int channels){
     int i,j,c;
     if(channels==2){
         for(i=0; i<len; i++){
             dst[2*i]   = float_to_int16_one(src+i);
-            dst[2*i+1] = float_to_int16_one(src+i+len);
+            dst[2*i+1] = float_to_int16_one(src+i+stride);
         }
     }else{
-        for(c=0; c<channels; c++, src+=len)
+        for(c=0; c<channels; c++, src+=stride)
             for(i=0, j=c; i<len; i++, j+=channels)
                 dst[j] = float_to_int16_one(src+i);
     }
Index: dsputil.h
===================================================================
--- dsputil.h	(revision 14207)
+++ dsputil.h	(working copy)
@@ -372,7 +372,7 @@
     /* C version: convert floats from the range [384.0,386.0] to ints in [-32768,32767]
      * simd versions: convert floats from [-32768.0,32767.0] without rescaling and arrays are 16byte aligned */
     void (*float_to_int16)(int16_t *dst, const float *src, long len);
-    void (*float_to_int16_interleave)(int16_t *dst, const float *src, long len, int channels);
+    void (*float_to_int16_interleave)(int16_t *dst, const float *src, long len, long stride, int channels);
 
     /* (I)DCT */
     void (*fdct)(DCTELEM *block/* align 16*/);
Index: i386/dsputil_mmx.c
===================================================================
--- i386/dsputil_mmx.c	(revision 14236)
+++ i386/dsputil_mmx.c	(working copy)
@@ -2156,32 +2156,31 @@
 
 #define FLOAT_TO_INT16_INTERLEAVE(cpu, body) \
 /* gcc pessimizes register allocation if this is in the same function as float_to_int16_interleave_sse2*/\
-static av_noinline void float_to_int16_interleave2_##cpu(int16_t *dst, const float *src, long len, int channels){\
-    DECLARE_ALIGNED_16(int16_t, tmp[len*channels]);\
+static av_noinline void float_to_int16_interleave2_##cpu(int16_t *dst, const float *src, long len, long stride, int channels){\
+    DECLARE_ALIGNED_16(int16_t, tmp[len]);\
     int i,j,c;\
-    float_to_int16_##cpu(tmp, src, len*channels);\
-    for(c=0; c<channels; c++){\
-        int16_t *ptmp = tmp+c*len;\
+    for(c=0; c<channels; c++, src+=stride){\
+        float_to_int16_##cpu(tmp, src, len);\
         for(i=0, j=c; i<len; i++, j+=channels)\
-            dst[j] = ptmp[i];\
+            dst[j] = tmp[i];\
     }\
 }\
 \
-static void float_to_int16_interleave_##cpu(int16_t *dst, const float *src, long len, int channels){\
+static void float_to_int16_interleave_##cpu(int16_t *dst, const float *src, long len, long stride, int channels){\
     if(channels==1)\
         float_to_int16_##cpu(dst, src, len);\
     else if(channels>2)\
-        float_to_int16_interleave2_##cpu(dst, src, len, channels);\
+        float_to_int16_interleave2_##cpu(dst, src, len, stride, channels);\
     else{\
-        float *src1;\
+        const float *src1 = src+stride;\
         asm volatile(\
             "shl $2, %0 \n"\
             "add %0, %1 \n"\
             "add %0, %2 \n"\
-            "lea (%2,%0), %3 \n"\
+            "add %0, %3 \n"\
             "neg %0 \n"\
             body\
-            :"+r"(len), "+r"(dst), "+r"(src), "=r"(src1)\
+            :"+r"(len), "+r"(dst), "+r"(src), "+r"(src1)\
         );\
     }\
 }
Index: vorbis_dec.c
===================================================================
--- vorbis_dec.c	(revision 14207)
+++ vorbis_dec.c	(working copy)
@@ -1577,7 +1577,7 @@
 
     AV_DEBUG("parsed %d bytes %d bits, returned %d samples (*ch*bits) \n", get_bits_count(gb)/8, get_bits_count(gb)%8, len);
 
-    vc->dsp.float_to_int16_interleave(data, vc->ret, len, vc->audio_channels);
+    vc->dsp.float_to_int16_interleave(data, vc->ret, len, len, vc->audio_channels);
     *data_size=len*2*vc->audio_channels;
 
     return buf_size ;
Index: wmadec.c
===================================================================
--- wmadec.c	(revision 14207)
+++ wmadec.c	(working copy)
@@ -715,9 +715,7 @@
 /* decode a frame of frame_len samples */
 static int wma_decode_frame(WMACodecContext *s, int16_t *samples)
 {
-    int ret, i, n, ch, incr;
-    int16_t *ptr;
-    float *iptr;
+    int ret, ch;
 
 #ifdef TRACE
     tprintf(s->avctx, "***decode_frame: %d size=%d\n", s->frame_count++, s->frame_len);
@@ -734,19 +732,12 @@
             break;
     }
 
-    /* convert frame to integer */
-    n = s->frame_len;
-    incr = s->nb_channels;
+    s->dsp.float_to_int16_interleave(samples, s->frame_out[0], s->frame_len,
+                                     s->frame_out[1]-s->frame_out[0], s->nb_channels);
+
     for(ch = 0; ch < s->nb_channels; ch++) {
-        ptr = samples + ch;
-        iptr = s->frame_out[ch];
-
-        for(i=0;i<n;i++) {
-            *ptr = av_clip_int16(lrintf(*iptr++));
-            ptr += incr;
-        }
         /* prepare for next block */
-        memmove(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],
+        memcpy(&s->frame_out[ch][0], &s->frame_out[ch][s->frame_len],
                 s->frame_len * sizeof(float));
     }
 



More information about the ffmpeg-devel mailing list